ROW_NUMBER / RANK / DENSE_RANK
Оконные функции нумерации строк. Различаются поведением при одинаковых значениях.
ROW_NUMBER() OVER ([PARTITION BY col] ORDER BY col)
RANK() OVER (...)
DENSE_RANK() OVER (...)Объяснение
Пример
-- Топ-3 сотрудника по зарплате в каждом отделе
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn
FROM employees
)
SELECT * FROM ranked WHERE rn <= 3;Связанные термины
Анекдоты по теме
Разработчик: — У меня запрос на 8 таблиц через JOIN, подзапросы, оконные функции внутри WHERE и GROUP BY на хэш с миллиардом строк. Он идёт 3 дня. Как оптимизировать? DBA: — TRUNCATE TABLE карьера_разработчика. И иди в менеджеры.
Аналитик хочет топ-3 продукта в каждой категории. Пишет GROUP BY, ORDER BY, LIMIT 3. Получает топ-3 вообще, не по категориям. DBA: тебе нужна оконная функция. ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) Потом WHERE rn <= 3. Аналитик: почему это не просто LIMIT 3 внутри GROUP BY?! DBA: потому что SQL так работает.
LEAD() смотрит вперёд. LAG() смотрит назад. Они никогда не встречаются в одной строке результата. Но в одном запросе — пожалуйста: SELECT LAG(price) OVER w, LEAD(price) OVER w FROM prices WINDOW w AS (ORDER BY date);