Использование MySQL:
MySQL не имеет функции ранжирования, но позволяет создавать и обновлять переменные:
SELECT x.grade,
x.name,
x.numberoflaps
FROM (SELECT s.grade,
s.name,
s.numberoflaps,
CASE
WHEN @grade != s.grade THEN @rownum := 1
ELSE @rownum := @rownum + 1
END AS rank,
@grade := s.grade
FROM STUDENTS s,
(SELECT @rownum := 0, @grade := NULL) r
ORDER BY s.grade, s.numberoflaps DESC) x
WHERE x.rank <= 2
ORDER BY x.grade, x.rank
Значение ORDER BY
в подзапросе важно, иначе ранжирование не будет выполнено должным образом.
Использование Oracle 9i + / SQL Server 2005 +:
Использование CTE:
WITH laps AS (
SELECT s.grade,
s.name,
s.numberoflaps,
ROW_NUMBER() OVER (PARTITION BY grade ORDER BY numberoflaps DESC) AS rank
FROM STUDENTS s)
SELECT l.grade,
l.name,
l.numberoflaps
FROM laps l
WHERE l.rank <= 2
ORDER BY l.grade, l.numberoflaps DESC
Эквивалент без CTE:
SELECT l.grade,
l.name,
l.numberoflaps
FROM (SELECT s.grade,
s.name,
s.numberoflaps,
ROW_NUMBER() OVER (PARTITION BY grade ORDER BY numberoflaps DESC) AS rank
FROM STUDENTS s) l
WHERE l.rank <= 2
ORDER BY l.grade, l.numberoflaps DESC
Оговорка:
Oracle получила функциональность ранжирования в 9i; для SQL Server это был 2005 год.