Die richtige Lösung ist:
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
Wie es funktioniert:
Es stimmt mit jeder Zeile von o
überein mit allen Zeilen von b
mit dem gleichen Wert in der Spalte Group
und einen größeren Wert in der Spalte Age
. Jede Zeile von o
nicht den Höchstwert seiner Gruppe in der Spalte Age
hat stimmt mit einer oder mehreren Zeilen von b
überein .
Der LEFT JOIN
lässt es die älteste Person in der Gruppe (einschließlich der Personen, die allein in ihrer Gruppe sind) mit einer Reihe voller NULL
abgleichen s von b
('kein höchstes Alter in der Gruppe').
Mit INNER JOIN
bewirkt, dass diese Zeilen nicht übereinstimmen und ignoriert werden.
Das WHERE
-Klausel behält nur die Zeilen mit NULL
s in den aus b
extrahierten Feldern . Sie sind die ältesten Personen aus jeder Gruppe.
Weiterführende Literatur
Diese Lösung und viele andere werden im Buch SQL Antipatterns:Avoiding the Pitfalls of Database Programming erklärt