Правилното решение е:
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
Как работи:
Той съответства на всеки ред от o
с всички редове от b
имащи същата стойност в колона Group
и по-голяма стойност в колона Age
. Всеки ред от o
няма максимална стойност на своята група в колона Age
ще съответства на един или повече редове от b
.
LEFT JOIN
го прави да съответства на най-възрастния човек в групата (включително хората, които са сами в групата си) с ред, пълен с NULL
s от b
(„няма най-голяма възраст в групата“).
Използване на INNER JOIN
прави тези редове да не съвпадат и те се игнорират.
WHERE
клаузата запазва само редовете с NULL
s в полетата, извлечени от b
. Те са най-възрастните от всяка група.
Допълнителни прочити
Това решение и много други са обяснени в книгата SQL Antipatterns:Избягване на клопките на програмирането на бази данни