Агрегация и группировка

GROUP BY и HAVING

Содержание курса

HAVING: условие на агрегат и фиксированный порядок предложений запроса

После того как GROUP BY сформировал группы и вычислил агрегаты, встаёт вопрос: как оставить только те группы, которые удовлетворяют какому-то условию? Это задача HAVING.

Предположим, нужно найти только те категории товаров, в которых суммарная стоимость запасов превышает 10 000:

SELECT category, SUM(price) AS итого
FROM products
GROUP BY category
HAVING SUM(price) > 10000;

Важно понимать момент применения: HAVING видит результат уже вычисленного агрегата. Движок сначала строит все группы, считает SUM(price) для каждой, а потом проверяет условие. Группы, не прошедшие проверку, просто не попадают в итог.

В условии HAVING можно использовать любую агрегатную функцию — ту же, что в SELECT, или другую. Например, отобрать категории, где одновременно больше трёх товаров и средняя цена выше 500:

SELECT category, COUNT(*) AS количество, AVG(price) AS средняя_цена
FROM products
GROUP BY category
HAVING COUNT(*) > 3 AND AVG(price) > 500;

Теперь о порядке предложений — он фиксирован синтаксисом SQL и не подлежит перестановке:

SELECTFROMWHEREGROUP BY … HAVING … ORDER BY … LIMIT

Если написать HAVING перед GROUP BY или ORDER BY перед HAVING, SQLite вернёт синтаксическую ошибку. Порядок отражает логику выполнения: сначала выбираем таблицу (FROM), фильтруем строки (WHERE), группируем (GROUP BY), фильтруем группы (HAVING), сортируем (ORDER BY) и ограничиваем количество (LIMIT). Зная этот порядок, вы всегда можете восстановить правильный синтаксис запроса любой сложности.