Короткий ответ
В PostgreSQL выражение DATE_TRUNC('month', order_date) приводит все даты одного месяца к общей границе. Затем GROUP BY создаёт одну группу на месяц, а COUNT и SUM вычисляют метрики.
Как это работает подробнее
Группировка по полноценной границе месяца сохраняет год. В отличие от неё, EXTRACT(MONTH FROM order_date) объединит, например, январь 2024 и январь 2025 в одну группу.
Диалекты отличаются: BigQuery использует DATE_TRUNC(order_date, MONTH), а ClickHouse — toStartOfMonth(order_date).
Пример кода
query.sql
SELECT
DATE_TRUNC('month', order_date) AS month_start,
COUNT(*) AS orders_cnt,
SUM(amount) AS total_amount
FROM orders
GROUP BY DATE_TRUNC('month', order_date)
ORDER BY month_start;Что использовать на практике
- Группируйте по дате месяца. Это сохраняет хронологию и позволяет корректно сортировать несколько лет.
- Сверяйте итог. Сумма месячных продаж должна совпасть с общей суммой за тот же фильтрованный период.
Подводные камни
- COUNT(*). Он считает строки заказов; если после соединения один заказ размножен, метрика будет завышена.
- Пропущенные месяцы. Агрегация не создаёт месяцы без заказов; для полного ряда нужен календарь дат.