Перейти к основному содержимому
Модуль 6 · Урок 2 из 422/57 в курсе~12 min
Уроки модуля (2/4)

Функции даты и времени

Даты и временные метки повсюду: заказы, логины, события, выставление счетов. В в этом уроке мы увидим, как извлекать части из даты (год, месяц…), усечь его до детализации (месяц, неделя…), вычислить интервалы и различия, а также проводить сравнения между периодами.

Базовые типы

PostgreSQL различает:

  • DATE — только дата, формат YYYY-MM-DD;
  • TIMESTAMP — дата+время, без часового пояса;
  • TIMESTAMPTZ — дата+время+часовой пояс;
  • INTERVAL — точка (например, '3 days', '2 hours 30 minutes').

В нашем наборе данных ecommerce:

СтолбецТип
customers.signed_up_onDATE
orders.ordered_atTIMESTAMP
orders.shipped_atTIMESTAMP (может быть NULL)

ЭКСТРАКТ — чтение части

EXTRACT(part FROM date) извлекает число:

SQL
SELECT EXTRACT(YEAR  FROM ordered_at) AS year,
       EXTRACT(MONTH FROM ordered_at) AS month,
       EXTRACT(DOW   FROM ordered_at) AS day_of_week  -- 0=domenica
FROM   orders;

Наиболее часто используемые части: YEAR, MONTH, DAY, HOUR, MINUTE, DOW (день недели 0–6), DOY (день года).

DATE_TRUNC — округление в меньшую сторону

DATE_TRUNC('part', date) «усекает» дату до детализации. Это необходимо для агрегирования по месяцу, неделе, часу:

SQL
-- Tutti gli ordini fatti in "marzo 2025" cadono nello stesso bucket:
SELECT DATE_TRUNC('month', ordered_at) AS month,
       COUNT(*) AS order_count
FROM   orders
GROUP BY month
ORDER BY month;

Допустимые части: 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'.

Для удобства чтения люди часто используют DATE, когда время не требуется: DATE_TRUNC('month', ordered_at)::date.

Различия и интервалы

Вычитание двух TIMESTAMP дает INTERVAL:

SQL
SELECT id,
       shipped_at - ordered_at AS wait_time
FROM   orders
WHERE  shipped_at IS NOT NULL;

Сравнение с литералом INTERVAL:

SQL
WHERE  shipped_at - ordered_at > INTERVAL '1 day'

Добавление дней к дате:

SQL
SELECT signed_up_on + INTERVAL '30 days' AS trial_expiration
FROM   customers;

Попробуйте это

Упражнение#sql.m6.l2.e1
Попыток: 0Загрузка…

Посчитайте, сколько заказов было размещено за год. Два столбца: год (целое число) и order_count. Упорядочить по годам по возрастанию.

Загрузка редактора…
Показать подсказку

EXTRACT(YEAR FROMorder_at) возвращает ЧИСЛО: приведите его к int с помощью ::int для удобства чтения.

Решение доступно после 3 попыток

Обзор упражнения

Упражнение#sql.m6.l2.e2
Попыток: 0Загрузка…

Для каждого месяца 2024 года укажите первый день месяца (столбец месяц, тип даты) и количество заказов. Заказ по месяцам.

Загрузка редактора…
Показать подсказку

DATE_TRUNC('месяц',order_at) возвращает первый день месяца в виде отметки времени; ::date преобразует его в дату.

Решение доступно после 3 попыток