How do you get the rows that contain the max value for each grouped set?
I've seen some overly-complicated variations on this question, and none with a good answer. I've tried to put together the simplest possible example:
Given a table like that below, with person, group, and age columns, how would you get the oldest person in each group? (A tie within a group should give the first alphabetical result)
Person | Group | Age
---
Bob | 1 | 32
Jill | 1 | 34
Shawn| 1 | 42
Jake | 2 | 29
Paul | 2 | 36
Laura| 2 | 39
Desired result set:
Shawn | 1 | 42
Laura | 2 | 39
Using CTEs - Common Table Expressions:
This is how I'm getting the N max rows per group in mysql
how it works:
co.country = ci.country
) < 1
so for 3 elements - ) < 3co.id < ci.id
Full example here:
mysql select n max values per group
My simple solution for SQLite (and probably MySQL):
However it doesn't work in PostgreSQL and maybe some other platforms.
In PostgreSQL you can use DISTINCT ON clause:
axiac's solution is what worked best for me in the end. I had an additional complexity however: a calculated "max value", derived from two columns.
Let's use the same example: I would like the oldest person in each group. If there are people that are equally old, take the tallest person.
I had to perform the left join two times to get this behavior:
Hope this helps! I guess there should be better way to do this though...
The correct solution is:
How it works:
It matches each row from
o
with all the rows fromb
having the same value in columnGroup
and a bigger value in columnAge
. Any row fromo
not having the maximum value of its group in columnAge
will match one or more rows fromb
.The
LEFT JOIN
makes it match the oldest person in group (including the persons that are alone in their group) with a row full ofNULL
s fromb
('no biggest age in the group').Using
INNER JOIN
makes these rows not matching and they are ignored.The
WHERE
clause keeps only the rows havingNULL
s in the fields extracted fromb
. They are the oldest persons from each group.Further readings
This solution and many others are explained in the book SQL Antipatterns: Avoiding the Pitfalls of Database Programming