Prawidłowe rozwiązanie to:
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
Jak to działa:
Pasuje do każdego wiersza z o
ze wszystkimi wierszami z b
o tej samej wartości w kolumnie Group
i większą wartość w kolumnie Age
. Dowolny wiersz od o
nie ma maksymalnej wartości swojej grupy w kolumnie Age
dopasuje jeden lub więcej wierszy z b
.
LEFT JOIN
sprawia, że pasuje do najstarszej osoby w grupie (w tym osób, które są same w grupie) z wierszem pełnym NULL
s z b
(„brak największego wieku w grupie”).
Korzystanie z INNER JOIN
sprawia, że te wiersze nie pasują i są ignorowane.
WHERE
Klauzula zachowuje tylko wiersze mające NULL
s w polach wyodrębnionych z b
. Są to najstarsze osoby z każdej grupy.
Dalsze lektury
To rozwiązanie i wiele innych wyjaśniono w książce Antywzorce SQL:unikanie pułapek programowania baz danych