Reputation: 332
If I have a table...
name | day | showers
-----|-----|--------
John | mon | 1
John | tue | 2
John | wed | 1
Pete | fri | 3
and I want to return the table of each persons day with the most showers...
name | day | showers
-----|-----|--------
John | tue | 2
Pete | fri | 3
How would I do this?
I thought I could do...
SELECT name, day FROM table GROUP BY name WHERE showers=max(showers)
but I get a syntax error due to day not being in the group by clause
Upvotes: 0
Views: 75
Reputation: 191
You can use this query:
SELECT name, days, showers
FROM test
WHERE showers =
(SELECT max(showers) FROM test i WHERE i.name = test.name)
A correlated subquery is one way of reading every row in a table and comparing values in each row against related data. It is used whenever a subquery must return a different result or set of results for each candidate row considered by the main query. In other words, you can use a correlated subquery to answer a multipart question whose answer depends on the value in each row processed by the parent statement.
So from the original table on the left, by running this query, you get the result in the table on the right
Upvotes: 0
Reputation: 5803
You could use an uncorrelated subquery
. This will keep the ties as well
select *
from t
where (name, showers) in (select name, max(showers)
from t
group by name);
Can also be expressed as a correlated subquery
select *
from t t1
where showers= (select max(t2.showers)
from t t2
where t1.name=t2.name);
Upvotes: 1
Reputation: 1271231
Use distinct on
:
select distinct on (name) t.*
from t
order by name, showers desc;
This returns exactly one row per name. If you want duplicates if there are ties, then use rank()
or dense_rank()
:
select t.*
from (select t.*,
rank() over (partition by name order by showers desc) as seqnum
from t
) t
where seqnum = 1;
Upvotes: 2