Den korrekta lösningen är:
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
Så fungerar det:
Den matchar varje rad från o
med alla rader från b
har samma värde i kolumnen Group
och ett större värde i kolumnen Age
. Vilken rad som helst från o
inte har maxvärdet för sin grupp i kolumnen Age
kommer att matcha en eller flera rader från b
.
LEFT JOIN
gör att den matchar den äldsta personen i gruppen (inklusive de personer som är ensamma i sin grupp) med en rad full av NULL
s från b
('ingen största ålder i gruppen').
Använda INNER JOIN
gör att dessa rader inte matchar och de ignoreras.
WHERE
satsen behåller endast raderna som har NULL
s i fälten extraherade från b
. De är de äldsta personerna från varje grupp.
Ytterligare avläsningar
Denna lösning och många andra förklaras i boken SQL Antipatterns:Avoiding the Pitfalls of Database Programming