Раздел 42 · Аналитика данных с нуля

DATE_TRUNC, EXTRACT и интервалы

junior~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Отто · операционный директор доставки «Гонец»

Ладно, с поясами разобрались. Теперь главное: когда у нас пик? По часам и по дням недели, мне под это ставить смены. И сколько в среднем едет заказ от кнопки до двери?

В прошлом уроке ты научился приводить время к одним часам. Теперь его надо резать: на часы, дни, недели. И вычитать одно время из другого, чтобы получить длительность.

Округлить или вырезать

Есть две разные операции, и их легко спутать.

Первая похожа на вопрос «на какой неделе это было». Ты берёшь момент и округляешь его вниз до начала периода: 17 марта, вторник, 14:32 превращается в «неделя с 16 марта». Это делает date_trunc.

Вторая похожа на вопрос «в котором часу». Ты вырезаешь из времени одну часть и получаешь число: 14. Это делает extract.

date_trunc нужен, когда строишь динамику: заказы по дням, неделям, месяцам. extract нужен, когда ищешь повторяющийся рисунок: какой час или день недели самый загруженный, независимо от даты.

DATE_TRUNC: заказы по неделям

SELECT date_trunc('week', created_at) AS week,
       count(*) AS orders
FROM orders
GROUP BY 1
ORDER BY 1;
 week                | orders
---------------------+--------
 2026-02-23 00:00:00 |    323
 2026-03-02 00:00:00 |   2562
 2026-03-09 00:00:00 |   2250
 ...
 2026-06-22 00:00:00 |   2415
 2026-06-29 00:00:00 |    727

Неделя в PostgreSQL начинается с понедельника. 1 марта 2026 года это воскресенье, поэтому первая «неделя» начинается 23 февраля и содержит один день данных. Последняя тоже неполная: 29 и 30 июня. Обычная неделя «Гонца» это 2200-2500 заказов.

GROUP BY 1 значит «группировать по первому столбцу SELECT». Так не приходится повторять длинное выражение дважды.

Мы берём created_at без перевода: сайт пишет его по местным часам, а Отто нужны местные дни и недели. С полем из приложения курьера (delivered_at, timestamptz) пришлось бы сначала сделать AT TIME ZONE 'Asia/Yekaterinburg', иначе граница суток прошла бы в пять утра по Екатеринбургу.

урок из курса

Урок из курса «Аналитика данных с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.