Получить доступ

Напиши SQL-запрос, возвращающий вторую по величине зарплату из таблицы employee(id, salary).

JuniorSQL-запросыSQL
Ещё спрашивают так:
  • Как найти N-ю по величине зарплату?
  • Чем RANK отличается от DENSE_RANK?
Коротко

SELECT DISTINCT salary FROM employee ORDER BY salary DESC LIMIT 1 OFFSET 1 — или подзапрос с MAX, или оконная функция DENSE_RANK.

  • DISTINCT обязателен: при двух одинаковых максимальных зарплатах вторая — следующая отличная
  • Если второй нет, запрос с LIMIT вернёт пустоту; обёртка в подзапрос вернёт NULL
  • DENSE_RANK обобщается на N-ю зарплату и на «в каждом отделе»

А ещё RANK пропускает номера после равных, DENSE_RANK — нет, ROW_NUMBER — нумерует всё подряд

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Вариант 1 — сортировка и смещение:

SELECT DISTINCT salary FROM employee ORDER BY salary DESC LIMIT 1 OFFSET 1;

Без DISTINCT при двух сотрудниках с максимальной зарплатой вернётся максимальная же. Если вторая зарплата отсутствует, результат пустой; чтобы вернуть NULL, оборачивают: SELECT (SELECT ... ) AS second_salary.

Вариант 2 — подзапрос:

SELECT max(salary) FROM employee WHERE salary < (SELECT max(salary) FROM employee);

Возвращает NULL, если второй нет; хорошо читается, но плохо обобщается на N.

Вариант 3 — оконная функция:

SELECT DISTINCT salary FROM (
  SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS r FROM employee
) t WHERE r = 2;

Обобщается на N-ю и на группы: PARTITION BY department_id — вторая зарплата в каждом отделе.

Ранжирующие функции: для зарплат 300, 300, 200: ROW_NUMBER — 1, 2, 3; RANK — 1, 1, 3; DENSE_RANK — 1, 1, 2. Для «второй по величине» нужен DENSE_RANK.

Пример

Заготовка:

-- таблица employee(id, salary)
SELECT ...

Что хотят услышать

  • Рабочий запрос с учётом дубликатов.
  • Поведение при отсутствии второй зарплаты.
  • Альтернативы, особенно оконная функция для N-й и по группам.
  • Различие ROW_NUMBER, RANK, DENSE_RANK.

Частые ошибки

  • Забыть DISTINCT.
  • Использовать RANK и получить пропуск номера.

Что спросят дальше

  • Как обобщить до N-й по величине?
  • Чем RANK отличается от DENSE_RANK?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем