Агрегаты, GROUP BY и HAVING
Сворачиваем множество строк в итоговые числа и группируем данные по категориям.
Агрегатная функция сворачивает множество строк в одно значение — сумму, среднее, количество — обычно в разрезе групп, заданных
GROUP BY.
Агрегатные функции
Пять основных функций отвечают на вопросы «сколько», «на какую сумму», «в среднем».
| Функция | Что считает |
COUNT(*) | количество строк |
SUM(x) | сумму значений |
AVG(x) | среднее |
MIN(x) / MAX(x) | минимум / максимум |
Считаем по всей таблице
Без группировки агрегат сворачивает всю таблицу в одну строку. Запустите пример.
CREATE TABLE sales (
id INTEGER PRIMARY KEY,
region TEXT,
amount INTEGER
);
INSERT INTO sales (id, region, amount) VALUES
(1, 'Север', 100), (2, 'Север', 200), (3, 'Юг', 150),
(4, 'Юг', 300), (5, 'Юг', 50), (6, 'Север', 400);
SELECT COUNT(*) AS cnt, SUM(amount) AS total, AVG(amount) AS avg_amount
FROM sales;
Вывод:
cnt|total|avg_amount 6|1200|200.0
GROUP BY — считаем по группам
Самое интересное начинается с группировки. GROUP BY region разбивает строки на группы по региону, и агрегат считается внутри каждой.
SELECT region,
COUNT(*) AS deals,
SUM(amount) AS total
FROM sales
GROUP BY region
ORDER BY total DESC;
Вывод:
Север|3|700 Юг|3|500
Ключевое правило: в SELECT при группировке могут быть только столбцы из GROUP BY и агрегаты. Нельзя выбрать id рядом с SUM(amount) — у группы нет одного id.
HAVING — фильтр для групп
WHERE фильтрует строки до группировки, а HAVING — уже готовые группы по их агрегатам. Это разные этапы.
SELECT region, SUM(amount) AS total
FROM sales
GROUP BY region
HAVING SUM(amount) > 600;
Вывод:
Север|700
Группа «Юг» (500) отсеялась, осталась только та, чья сумма больше 600. Запомните порядок: сначала WHERE отбирает строки, потом GROUP BY группирует, и только затем HAVING фильтрует группы.
WHERE и HAVING вместе
-- Считаем только крупные сделки (WHERE), потом отбираем щедрые регионы (HAVING)
SELECT region, COUNT(*) AS big_deals
FROM sales
WHERE amount >= 150
GROUP BY region
HAVING COUNT(*) >= 2;
Вывод:
Юг|2
Итог
- Агрегаты
COUNT,SUM,AVG,MIN,MAXсворачивают строки в одно число. GROUP BYсчитает агрегат внутри каждой группы; вSELECTдопустимы только группирующие столбцы и агрегаты.WHEREфильтрует строки до группировки,HAVING— готовые группы по агрегатам.