WHERE фильтрует отдельные строки до группировки, а HAVING фильтрует уже собранные группы.
Если вопрос звучит как «оставить категории, где сумма больше порога» или «клиентов с двумя заказами», почти всегда нужен GROUP BY и HAVING.
Эта книга тренирует не абстрактный синтаксис, а реальные отчётные вопросы: выручка, маржа, повторные покупки, достаточная выборка и проблемные заказы.
Сначала прочитайте бизнес-вопрос и определите зерно отчёта: категория, клиент, дата, источник или товар.
Затем посмотрите, какие агрегаты участвуют в условии: COUNT, SUM, AVG или COUNT DISTINCT.
Все примеры маленькие и запускаются в SQLite, поэтому результат можно проверить вручную и только потом переносить идею в рабочие данные.
1. Оставить категории с двумя и более заказами
2. Найти продавцов с выручкой от 1000 рублей
3. Отобрать товары с высоким средним чеком
4. Проверить регионы с тремя активными клиентами
5. Найти дни с отрицательной маржей
6. Оставить каналы с конверсией выше 50 процентов
7. Найти авторов с двумя сильными книгами
8. Проверить товары с достаточным остатком
9. Оставить месяцы с ростом заказов
10. Найти клиентов с повторной покупкой
11. Убрать категории с маленькой выборкой перед сравнением
12. Найти проекты с перерасходом бюджета
13. Показать менеджеров с несколькими просрочками
14. Найти города с двумя складами
15. Отобрать пользователей с тремя сессиями
16. Сравнить источники с положительной прибылью
17. Проверить заказы с несколькими проблемами
18. Оставить сегменты с выручкой и активностью
Нужно найти категории, где было хотя бы два заказа, чтобы не делать выводы по единичной покупке.
CREATE TABLE orders(category TEXT, order_id INTEGER, revenue INTEGER);
INSERT INTO orders VALUES
('books',1,300),('books',2,500),('courses',3,1200),('templates',4,200),('templates',5,250);
SELECT category, COUNT(*) AS orders_count
FROM orders
GROUP BY category
HAVING COUNT(*) >= 2
ORDER BY category;
[["books", 2], ["templates", 2]]
HAVING фильтрует уже собранные группы, поэтому условие COUNT(*) >= 2 применяется после GROUP BY.
Запрос намеренно работает на маленькой таблице, поэтому результат можно проверить глазами до переноса приёма в рабочий отчёт.
ORDER BY или явная агрегация делают вывод устойчивым: строки не зависят от случайного порядка хранения данных.
Если написать COUNT(*) в WHERE, SQLite выдаст ошибку: агрегаты нельзя использовать до того, как группы собраны.
Какая категория исчезнет, если порог поднять до трёх заказов?
Ответ: Исчезнут обе категории из результата, потому что ни у одной нет трёх заказов.
Нужно быстро выделить продавцов, у которых суммарная выручка уже достаточно большая для отдельного разбора.
CREATE TABLE sales(seller TEXT, revenue INTEGER);
INSERT INTO sales VALUES
('Анна',400),('Анна',700),('Борис',900),('Вера',300),('Вера',500);
SELECT seller, SUM(revenue) AS total_revenue
FROM sales
GROUP BY seller
HAVING SUM(revenue) >= 1000
ORDER BY seller;
[["Анна", 1100]]
SUM(revenue) считается внутри каждого продавца, а HAVING оставляет только группы с нужной суммой.
Запрос намеренно работает на маленькой таблице, поэтому результат можно проверить глазами до переноса приёма в рабочий отчёт.
ORDER BY или явная агрегация делают вывод устойчивым: строки не зависят от случайного порядка хранения данных.
Фильтрация отдельных строк через WHERE revenue >= 1000 потеряла бы продавца Анна, хотя сумма её двух продаж больше порога.
Почему Борис не попал в результат? Объясните ответ, опираясь на строки исходных данных.
Ответ: У Бориса одна продажа на 900 рублей, а это меньше порога 1000 рублей.
Нужно найти товары, у которых средний чек выше 400 рублей, чтобы сравнить их с массовыми дешёвыми товарами.
CREATE TABLE order_items(sku TEXT, total INTEGER);
INSERT INTO order_items VALUES
('A1',300),('A1',500),('B2',900),('C3',150),('C3',250);
SELECT sku, ROUND(AVG(total), 1) AS avg_total
FROM order_items
GROUP BY sku
HAVING AVG(total) > 400
ORDER BY sku;
[["B2", 900.0]]
AVG(total) считается по каждой группе SKU, а ROUND нужен только для аккуратного отображения результата.
Запрос намеренно работает на маленькой таблице, поэтому результат можно проверить глазами до переноса приёма в рабочий отчёт.
На этой странице вы можете прочитать онлайн книгу «HAVING в SQL. 18 задач для отчётов», автора Глеб Зайцев. Данная книга имеет возрастное ограничение 12+, относится к жанрам: «Программирование», «Учебная литература». Произведение затрагивает такие темы, как «анализ данных», «обучение программированию». Книга «HAVING в SQL. 18 задач для отчётов» была написана в 2026 и издана в 2026 году. Приятного чтения!
О проекте
О подписке
Другие проекты