Время чтения: ~7 минут
Группировка данных позволяет превратить набор отдельных строк в категоризованные метрики. GROUP BY — ключевой оператор для отчетов, где нужны итоги по категориям, дням или любым другим признакам. В этом уроке вы разберете синтаксис GROUP BY, главное правило и практические примеры на Sakila. К концу урока вы сможете уверенно строить аналитические запросы с группировкой.
Группировка данных с помощью GROUP BY
В предыдущем уроке вы узнали об агрегатных функциях. Теперь идем дальше: как применять эти функции к разным категориям данных.
GROUP BY решает эту задачу, позволяя разбить данные на группы и считать метрики для каждой группы отдельно.
Синтаксис GROUP BY
Базовая структура:
SELECT column1, AGG_FUNCTION(column2)
FROM table
GROUP BY column1;
Главное правило
Когда используете GROUP BY, каждый столбец в SELECT должен:
- либо быть в списке
GROUP BY; - либо быть обёрнут в агрегатную функцию (
SUM,COUNT,AVG,MIN,MAX).
Это правило помогает избежать неоднозначности: SQL должен знать, какое значение вернуть для столбца, если в группе несколько строк.
Группировка по одному столбцу
Сумма платежей по каждому клиенту
SELECT customer_id, SUM(amount) AS total_paid
FROM payment
GROUP BY customer_id;
Результат: для каждого клиента одна строка с суммой его платежей.
Количество платежей по сотруднику
SELECT staff_id, COUNT(*) AS payments_count
FROM payment
GROUP BY staff_id;
Результат: для каждого сотрудника показано, сколько платежей он обработал.
Средний платеж по дате
SELECT DATE(payment_date) AS pay_date, AVG(amount) AS avg_payment
FROM payment
GROUP BY DATE(payment_date);
Результат: для каждой даты выводится средний размер платежа.
Вариант: GROUP BY с алиасом
SELECT DATE(payment_date) AS pay_date, AVG(amount) AS avg_payment
FROM payment
GROUP BY pay_date;
Примечание: этот вариант работает в MySQL/MariaDB, но не во всех СУБД. Для кросс-СУБД совместимости лучше писать GROUP BY DATE(payment_date) полностью.
Группировка по нескольким столбцам
Можно группировать по нескольким полям одновременно для более детального анализа.
Сумма платежей по сотруднику и клиенту
SELECT staff_id, customer_id, SUM(amount) AS total_paid
FROM payment
GROUP BY staff_id, customer_id;
Результат: для каждой пары (сотрудник, клиент) выводится сумма платежей.
Практические примеры
Отчет по выручке за каждый день
SELECT DATE(payment_date) AS pay_date, SUM(amount) AS total_sales
FROM payment
GROUP BY DATE(payment_date)
ORDER BY pay_date;
Самые активные клиенты по числу аренд
SELECT customer_id, COUNT(*) AS rentals_count
FROM rental
GROUP BY customer_id
ORDER BY rentals_count DESC;
Среднее количество фильмов по категориям
SELECT category_id, AVG(rental_rate) AS avg_rental_rate
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
GROUP BY category_id;
Часто задаваемые вопросы
Почему не все столбцы SELECT должны быть в GROUP BY?
Потому что агрегатные функции (SUM, COUNT, AVG) уже указывают, как обработать остальные строки группы. Если столбец не агрегирован, он должен быть в GROUP BY, иначе неясно, какое его значение выбрать.
Можно ли группировать по выражению, а не по столбцу?
Да, например GROUP BY DATE(payment_date) или GROUP BY YEAR(payment_date). Главное — выражение должно быть одинаковым в SELECT и GROUP BY.
Что будет, если GROUP BY пуст?
Это синтаксическая ошибка. GROUP BY всегда должен иметь хотя бы один столбец или выражение.
Вопросы для собеседования
Что такое GROUP BY и зачем оно нужно?
GROUP BY объединяет строки, где выбранные столбцы имеют одинаковые значения, в одну группу. К каждой группе можно применить агрегатные функции для получения сводных показателей.
Почему нельзя выбрать произвольный столбец, если используется GROUP BY?
Потому что в одной группе может быть несколько строк с разными значениями. SQL должен знать, какое значение вернуть для этого столбца, иначе результат неоднозначен. Поэтому столбец либо в GROUP BY, либо в функции.
Какая разница между WHERE и HAVING?
WHERE фильтрует строки ДО группировки, а HAVING фильтрует группы ПОСЛЕ группировки. Например, WHERE amount > 10 исключит строки до группировки, а HAVING SUM(amount) > 100 исключит группы с суммой менее 100.
Ключевые выводы этого урока:
GROUP BYпозволяет разбить данные на группы и применить агрегаты к каждой.- Главное правило: все столбцы в SELECT либо в GROUP BY, либо в агрегатной функции.
- Можно группировать по одному или нескольким столбцам одновременно.
- Можно группировать по выражениям, например
GROUP BY DATE(payment_date). GROUP BYиспользуется для отчетов, аналитики и получения итогов по категориям.
В следующем уроке мы разберем фильтрацию групп с помощью оператора HAVING.