Собесов

Максимальная зарплата по отделам с фильтром по средней

SQLАгрегацияЛёгкаяJunior

Условие

Из таблицы employees(name, department, salary) верните максимальную зарплату для каждого отдела, где средняя зарплата по отделу превышает 5000, отсортировав результат по названию отдела в алфавитном порядке.

Решение

SELECT department,
       MAX(salary) AS max_salary
FROM   employees
GROUP BY department
HAVING AVG(salary) > 5000
ORDER BY department;

Разбор

Часть Что делает
GROUP BY department Создаёт по группе на каждый отдел
MAX(salary) Самая большая зарплата в отделе
HAVING AVG(salary) > 5000 Оставляет отделы со средней > 5000
ORDER BY department Сортирует по названию отдела

Логический порядок выполнения

FROM → GROUP BY → HAVING → SELECT (агрегация) → ORDER BY

Поэтому в HAVING можно использовать агрегаты, а в WHERE — нельзя.

Можно ли в HAVING использовать колонку, которой нет в SELECT

Да: HAVING AVG(salary) > 5000 ссылается на агрегат, не выведенный в SELECT. Это валидно.

Эквивалентная запись через подзапрос

SELECT department, max_salary
FROM (
  SELECT department,
         MAX(salary) AS max_salary,
         AVG(salary) AS avg_salary
  FROM   employees
  GROUP BY department
) t
WHERE avg_salary > 5000
ORDER BY department;

Иногда читается яснее, но чаще делает то же самое.

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

  1. MAX(salary) vs «сотрудник с MAX» — задача просит число, а не имя. Если бы нужен был сотрудник, нужны окно RANK() или JOIN с подзапросом.
  2. Сотрудники с salary = NULL — будут проигнорированы при MAX/AVG (агрегаты пропускают NULL).
  3. Пустой отдел — если в отделе никого нет, его не будет в результате (нет строк → нет группы).
  4. HAVING SUM(salary) > 5000 — другое условие, не путать с AVG.

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

SELECT department, MAX(salary)
FROM   employees
GROUP BY department
HAVING AVG(salary) > 5000
ORDER BY department;

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

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

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