Как выбрать всех сотрудников с максимальной зарплатой в каждом департаменте с именем, зарплатой и названием департамента в SQL?
Что проверяют
Знаете ли вы оконные функции и подумали ли про ничью: в отделе может быть несколько человек с одинаковой максимальной зарплатой.
Как отвечать
Самое короткое и правильное решение через оконную функцию:
select name, salary, department
from (
select e.name, e.salary, d.name as department,
dense_rank() over (partition by e.department_id order by e.salary desc) as rnk
from employees e
join departments d on d.id = e.department_id
) t
where rnk = 1;Обязательно проговорите выбор функции: dense_rank вернёт всех, у кого зарплата максимальная, row_number оставит одного случайного из них. Какой вариант верный, зависит от постановки, и это стоит уточнить у интервьюера вслух.
Альтернативы, которые полезно назвать:
- соединение с агрегатом: подзапрос считает максимум по отделу, затем соединяется по паре «отдел и зарплата». Работает везде, включая старые версии;
- коррелированный подзапрос
where salary = (select max(salary) ...): читается легко, но на больших таблицах обычно медленнее; distinct onв PostgreSQL: самый компактный вариант, если нужен ровно один сотрудник на отдел.
Хорошо, если добавите про производительность: индекс по паре «отдел, зарплата» позволяет получить максимум без полного сканирования, а проверить это можно через EXPLAIN. И про крайние случаи: отдел без сотрудников не попадёт в результат при обычном соединении, для него нужен left join от таблицы отделов.
Где спотыкаются
Берут group by department и пытаются вытащить имя, получая ошибку или случайное значение.
Используют row_number и молча теряют половину ответов при одинаковых зарплатах.
Не спрашивают про ничью и решают задачу не так, как её задумывал интервьюер.