De juiste oplossing is:
SELECT o.*
FROM `Persons` o # 'o' from 'oldest person in group'
LEFT JOIN `Persons` b # 'b' from 'bigger age'
ON o.Group = b.Group AND o.Age < b.Age
WHERE b.Age is NULL # bigger age not found
Hoe het werkt:
Het komt overeen met elke rij van o
met alle rijen van b
met dezelfde waarde in kolom Group
en een grotere waarde in kolom Age
. Elke rij van o
niet de maximale waarde hebben van zijn groep in kolom Age
komt overeen met een of meer rijen uit b
.
De LEFT JOIN
zorgt ervoor dat het overeenkomt met de oudste persoon in de groep (inclusief de personen die alleen zijn in hun groep) met een rij vol NULL
s van b
('geen grootste leeftijd in de groep').INNER JOIN
gebruiken zorgt ervoor dat deze rijen niet overeenkomen en worden genegeerd.
De WHERE
clausule houdt alleen de rijen met NULL
s in de velden geëxtraheerd uit b
. Zij zijn de oudste personen van elke groep.
Verdere metingen
Deze oplossing en vele andere worden uitgelegd in het boek SQL Antipatterns:Avoiding the Pitfalls of Database Programming