Ответ вслух Middle Оконные функции спрашивают часто обновлено

Топ-N в каждой группе

Вопрос

Как вывести трёх самых высокооплачиваемых сотрудников в каждом отделе? Что делать с равными зарплатами?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Нумерую сотрудников внутри отдела оконной функцией: ROWNUMBER() OVER (PARTITION BY departmentid ORDER BY salary DESC, id). Фильтровать по ней в том же WHERE нельзя, оконные функции считаются позже, поэтому заворачиваю в подзапрос или CTE и снаружи пишу WHERE rn <= 3.

Что должно прозвучать в ответе

  • ROW_NUMBER/RANK/DENSE_RANK с PARTITION BY department_id ORDER BY salary DESC

  • Фильтр по номеру во внешнем запросе или CTE: окно нельзя в WHERE

  • Выбор функции зависит от требований к равенству: ровно 3 строки или все с равной зарплатой

  • Для ROW_NUMBER добавить второй ключ сортировки для детерминизма

  • Альтернативы: LATERAL с LIMIT 3, коррелированный подзапрос

  • Индекс (department_id, salary DESC) ускоряет вариант с LATERAL

Что могут спросить следом

  • Что вернёт DENSE_RANK <= 3, если у пятерых одинаковая зарплата?
  • Как сделать это без оконных функций?
  • Как это будет выполняться на 100 млн строк?

Разбор

Нумерую сотрудников внутри отдела оконной функцией: ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC, id). Фильтровать по ней в том же WHERE нельзя, оконные функции считаются позже, поэтому заворачиваю в подзапрос или CTE и снаружи пишу WHERE rn <= 3. Дальше вопрос к требованиям. Если нужно ровно три человека, беру ROW_NUMBER и второй ключ сортировки, чтобы результат был стабильным. Если при равенстве нужны все, кто делит третье место, беру RANK, а если нужны три разных уровня зарплаты, DENSE_RANK. Альтернатива, которая хорошо работает при индексе (department_id, salary DESC): JOIN LATERAL с ORDER BY salary DESC LIMIT 3 для каждого отдела, тогда база читает только по три строки из индекса на отдел.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме