Собесов

Хабр SQL — вторая по величине зарплата

SQLПодзапросы и оконные функцииЛёгкаяJunior

Условие

Дана таблица Employee(id int, salary int). Напишите SQL-запрос, который возвращает вторую по величине зарплату. Если такой зарплаты не существует (все одинаковые или одна запись), верните NULL.

Пример

id salary
1 100
2 200
3 300

Ожидаемый результат: 200.

id salary
1 100

Ожидаемый результат: NULL.

Решение

Подход 1 — подзапрос с MAX

Берём максимум среди тех, кто меньше глобального максимума. NULL появляется автоматически, если такого нет.

SELECT MAX(salary) AS second_highest
FROM Employee
WHERE salary < (SELECT MAX(salary) FROM Employee);

Подход 2 — DISTINCT + LIMIT/OFFSET

SELECT salary
FROM (SELECT DISTINCT salary FROM Employee ORDER BY salary DESC LIMIT 2) t
ORDER BY salary ASC
LIMIT 1;

Минус: если запись одна — вернёт ту же зарплату, а не NULL. Нужно дополнительно обработать.

Подход 3 — DENSE_RANK

SELECT salary
FROM (
  SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rk
  FROM Employee
) t
WHERE rk = 2
LIMIT 1;

DENSE_RANK корректно обрабатывает дубликаты: 300, 300, 200 → ранги 1, 1, 2.

Подход «правильный» с гарантированным NULL

SELECT (SELECT DISTINCT salary
        FROM Employee
        ORDER BY salary DESC
        LIMIT 1 OFFSET 1) AS second_highest;

Внешний SELECT без FROM превращает «пустую выборку» в NULL.

Подводные камни

  1. ROW_NUMBER вместо DENSE_RANK. Если два сотрудника имеют 300, ROW_NUMBER присвоит им 1 и 2 — и «вторая» зарплата вернётся как 300, что неправильно.
  2. LIMIT 1 OFFSET 1 без DISTINCT. Дубликат максимума будет считаться «второй».
  3. NULL-friendly. Подзапрос с MAX сам отдаёт NULL, остальные формы требуют обёртки.
  4. n-я по величине. Замените < MAX(...) на коррелированный подзапрос с COUNT(DISTINCT ...) или используйте DENSE_RANK() = N.

Эталонный ответ

SELECT MAX(salary) FROM Employee WHERE salary < (SELECT MAX(salary) FROM Employee); — самый компактный и NULL-безопасный вариант для второй по величине зарплаты.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти