В личной переписке мне совершенно справедливо заметили, что в постинге про выборку лучших учеников (Выбор максимального значения по группам в SQL) я, любуясь красотой решения через PARTITION, обошёл вниманием ещё одно решение, которое сочетает в себе универсальность первого и скорость второго.
Проверил, оно летает так же быстро, как второе. И при этом оно пойдёт на любой нормальной реляционной СУБД без модификаций, и даже может прийти в голову джуну.
По-русски формулируется почти так же, как второе. Надо найти лучшую успеваемость в каждом классе, а потом в каждом классе взять учеников с лучшей успеваемостью.
А на SQL это формулируется как соединение с вложенным запросом.
SELECT stud.Name
FROM Students stud
INNER JOIN
(
SELECT ClassId, MAX(Performance) as BestPerformance
FROM Students
GROUP BY ClassId
) best
ON stud.ClassId = best.ClassId
WHERE stud.Performance = best.BestPerformance
Выполняется, как второе, за O(n) (без учёта всяческих оптимизаций). На базе в десятки миллионов записей проскочило за треть секунды.
По сравнению с решением через ранг в партиции получилось всё же медленнее, но, во-первых, даже на базе в десятки миллионов записей разница в доли секунды, а во-вторых, такая разница в принципе может быть вопросом оптимизации базы.
Для сравнения – первый вариант (LEFT JOIN с выборкой только тех, у кого партнёра по соединению не нашлось) работал дольше минуты (потом я просто абортнул запрос).
Вывод – третий вариант решения лучший, т.к. сочетает универсальность и скорость.