Вернуть вторую по величине зарплату в каждом отделе
Таблица employees(department, salary). Верните вторую по величине зарплату в каждом отделе. Равные зарплаты считайте одним рангом, то есть нужно второе по величине уникальное значение. Отдел с одним уровнем зарплаты не возвращает ничего.
-- вторая по величине уникальная зарплата на отдел
Напишите запрос.
Ранжируют по отделу, затем берут ранг 2 снаружи — окно нельзя класть в WHERE. DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) приравнивает равные, поэтому ранг 2 — второе уникальное значение.
- ✗Использовать
ROW_NUMBER, который разделяет равные топ-зарплаты и сдвигает ранг 2 - ✗Применять
LIMIT/OFFSETглобально вместо разбивки по отделу - ✗Забывать, что результат окна фильтруют во внешнем запросе
- →Как изменится ответ, если нужен второй сотрудник, включая совпадения?
- →Почему
DENSE_RANKлучшеROW_NUMBER, когда зарплаты могут совпадать?
Ранжируют зарплаты внутри каждого отдела, затем во внешнем запросе оставляют ранг 2 — оконную функцию нельзя фильтровать прямо в WHERE:
SELECT department, salary
FROM (
SELECT department, salary,
DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rnk
FROM employees
) t
WHERE rnk = 2;
DENSE_RANK приравнивает равные зарплаты, поэтому ранг 2 — это второе по величине уникальное значение (а не второй сотрудник). ROW_NUMBER дал бы разные номера равным топ-зарплатам, и rn = 2 могло бы указать на второго сотрудника с тем же максимумом. LIMIT 1 OFFSET 1 работает глобально и не разбивает по отделам.