Уроки модуля (4/4)
Группы фильтрации: HAVING
Когда у вас есть результат по группе (предыдущий урок), вам часто захочется
оставлять только те группы, которые удовлетворяют условию: отделы с более
более 2 человек, проекты со средним бюджетом выше 100 тыс., пользователи с
не менее 10 заказов. Для этого WHERE недостаточно.
Почему ГДЕ недостаточно
WHERE фильтрует строки таблицы, перед агрегированием. Поэтому он не может видеть
результат COUNT(*) или AVG(...): к моменту запуска WHERE эти
значения еще не рассчитаны.
-- ERROR: COUNT(*) doesn't exist yet when WHERE is evaluated
SELECT department_id, COUNT(*) AS count
FROM employees
WHERE COUNT(*) > 2 -- ❌ doesn't work
GROUP BY department_id;Для фильтрации после агрегирования существует специальное предложение: HAVING.
Синтаксис
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column
HAVING condition_on_aggregate;-- Departments with more than 2 employees:
SELECT department_id, COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 2;HAVING для GROUP BY то же самое, что WHERE для FROM: та же идея
(«фильтр»), но применяется после группировки в совокупности.
Логический порядок предложений
Чтобы никогда больше не путать WHERE и HAVING, запомните порядок, в котором
SQL мысленно выполняет их:
FROM/JOIN— строит стартовую таблицу путем объединения источников.WHERE— удаляет ненужные строки.GROUP BY— собирает оставшиеся строки в группы.HAVING— удаляет группы, которые вам не интересны.SELECT— вычисляет итоговые столбцы (включая агрегаты).ORDER BY/LIMIT— изменить порядок и вырезать.
Важные примечания:
- в
WHEREможно использовать только столбцы таблицы; - в
HAVINGвы можете использовать группировку столбцов и агрегатов.
-- Classic combo: filter first, group, filter the groups, sort.
SELECT d.name, AVG(e.salary) AS average
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
WHERE e.hired_on >= '2018-01-01' -- filter rows
GROUP BY d.name
HAVING AVG(e.salary) > 35000 -- filter groups
ORDER BY average DESC;Попробуйте это
Для каждого отдела покажите название (departments.name) и количество сотрудников, НО только для отделов, в которых минимум 2 сотрудника. Две колонки, по одной строке на квалификационное отделение.
Показать подсказку
Условие «минимум 2» становится COUNT(*) >= 2 в HAVING.
Решение доступно после 3 попыток
Обзор упражнения
Укажите отделы (departments.name), средняя зарплата которых превышает 35000. Учитывайте только сотрудников, принятых на работу с 2018 года. Две колонки: имя и среднее значение. Сортировать по среднему убыванию.
Показать подсказку
ГДЕ фильтрует строки (сотрудники, принятые на работу с 2018 года), ИМЕЮ фильтрует группы (в среднем > 35000).
Решение доступно после 3 попыток