Joining DB records to the ‘highest’ of their related (1:m) data
I often have cause to query a database table and join it with a subtable of related data (i.e. a table with which this one has a one-to-many relationship), and to retrieve only the highest (or lowest) of related records (based on some sortable field; often a date). Usually in MySQL, and often to be used in a view and so sub-queries are not an option.
The key is to
-
Outer joinwith the subtable twice (well, the first join can be inner, if a subrecord result is required); - add, to the second join condition, the constraint that this second-subtable’s sorting field must be greater than its first-subtable counterpart; and
- add a
wherecondition that the second-subtable’s primary key be null.
Why this is so hard to remember, I do not know.
For example, for these two tables
id
|
|---|
| 1 |
| 2 |
| 3 |
id
|
|---|
| 1 |
| 2 |
| 3 |
| 4 |
the SQL is
SELECT *
FROM records r
LEFT JOIN subrecords s1 ON (s1.record_id = r.id)
LEFT JOIN subrecords s2 ON (s2.record_id = r.id AND s2.date > s1.date)
WHERE s2.id IS NULL
ORDER BY r.id
to give a result of
r
|
|
|---|---|
id
|
|
| 1 | |
| 2 | |
| 3 | |
Of course the list of selected columns needs to be changed.