Для получения топ-3 сотрудников с наибольшей зарплатой в каждом отделе я использую Common Table Expression (CTE) в комбинации с window function.
WITH ranked AS (
SELECT *,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employees
)
SELECT * FROM ranked WHERE rnk <= 3;
WITH ranked AS (...) определяет CTE, которое временно хранит отранжированный набор результатовDENSE_RANK() присваивает ранг каждому сотруднику в его отделе, упорядочивая по salary DESCPARTITION BY department_id обеспечивает сброс ранга для каждого отделаrnk <= 3, возвращая только топ-3 зарплатников в каждом отделеИспользование DENSE_RANK() — это осознанный выбор, который корректно работает с одинаковыми зарплатами:
DENSE_RANK() — присваивает одинаковый ранг совпадающим значениям без пропусков в нумерации (например, 1, 2, 2, 3)RANK() — присваивает одинаковый ранг совпадающим значениям, но пропускает следующий ранг (например, 1, 2, 2, 4)ROW_NUMBER() — присваивает уникальный ранг каждой строке, из-за чего при одинаковых зарплатах один из сотрудников может случайно выпасть из выборкиЭтот паттерн — CTE + window function + фильтр — стандартное и эффективное решение для задач типа «топ N по группам» в SQL, которое работает во всех основных БД, включая PostgreSQL, SQL Server и MySQL 8+.
Использование DENSE_RANK() вместо RANK() гарантирует, что если двое сотрудников в одном отделе получают одинаковую зарплату, оба будут включены без пропусков номеров рангов в последовательности.
Новый — ещё не проверен сообществом
Вы