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;Связанные термины
Анекдоты по теме
— Зачем нужен PARTITION BY? — Это GROUP BY для оконных функций. Но без схлопывания. — Пример? — SUM(salary) OVER (PARTITION BY department) — сумма зарплат по отделу для каждой строки.
Приходит запрос на свидание к оконной функции LAG(). — Пойдём со мной? — Нет, я люблю оглядываться на прошлое. Я буду смотреть на предыдущее значение, пока ты будешь говорить о настоящем. И вообще, без ORDER BY я не работаю.
Аналитик хочет топ-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 так работает.