Как сгруппировать продажи билетов по дням в SQL и получить дневную выручку
При анализе продаж билетов часто требуется вывести дневную выручку, сгруппировав данные по дате. Новички нередко сталкиваются с проблемой: запрос не группирует строки и выводит каждую продажу отдельно. Разберём типичные ошибки и покажем правильное решение на примере таблицы payment.
Почему запрос с SUM и OVER не даёт группировки?
В первом примере используется оконная функция SUM(amount) OVER (ORDER BY payment_date). Она вычисляет накопительную сумму для каждой строки, а не суммирует значения за день. Результат - все строки остаются, но с нарастающим итогом. Для группировки по дате нужен GROUP BY.
Почему GROUP BY не группирует по дате?
Во втором примере GROUP BY date не работает, потому что date - это псевдоним столбца payment_date, который содержит дату и время. Каждая строка имеет уникальное время, поэтому группировка происходит по каждой микросекунде. Нужно привести дату к формату DATE.
Правильный запрос: группировка по дате с SUM
Используйте функцию DATE(payment_date) для извлечения только даты и примените GROUP BY к этому значению. Пример:
SELECT
DATE(payment_date) AS date,
SUM(amount) AS daily_income
FROM payment
WHERE MONTH(payment_date) = 7 AND YEAR(payment_date) = 2005
GROUP BY DATE(payment_date)
ORDER BY date;Этот запрос вернёт одну строку на каждую дату с общей суммой продаж за день.
Дополнительные советы по оптимизации
- Используйте
CAST(payment_date AS DATE)вместоDATE()для совместимости с разными СУБД. - Для больших таблиц создайте индекс по столбцу
payment_date- это ускорит фильтрацию и группировку. - Если нужно получить выручку за несколько дней без разбивки по часам, группировка по
DATE- оптимальное решение.
Типичные ошибки и их исправление
Ошибка 1: использование GROUP BY payment_date - группировка по полной дате и времени. Исправление: приводите к дате. Ошибка 2: применение оконной функции без GROUP BY - получаете накопительный итог. Исправление: замените на SUM с GROUP BY.