Read the book: «HAVING в SQL. 18 задач для отчётов»
Перед первой задачей
Почему HAVING часто путают с WHERE
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. Оставить сегменты с выручкой и активностью
Практические задачи
Задача 1. Оставить категории с двумя и более заказами
Рабочий вопрос
Нужно найти категории, где было хотя бы два заказа, чтобы не делать выводы по единичной покупке.
Данные
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 выдаст ошибку: агрегаты нельзя использовать до того, как группы собраны.
Самостоятельная проверка
Какая категория исчезнет, если порог поднять до трёх заказов?
Ответ: Исчезнут обе категории из результата, потому что ни у одной нет трёх заказов.
The free sample has ended.