SQL·Средний·12 мин
Функции работы с датами в SQL
DATE_TRUNC, EXTRACT, DATE_PART — как группировать и форматировать даты.
Функции работы с датами в SQL
Даты — главная боль и главное удовольствие SQL-аналитика. От «выручка по месяцам» до «сколько прошло с последнего входа» — всё через date-функции.
Текущая дата/время
SELECT
CURRENT_DATE, -- 2026-06-17
CURRENT_TIME, -- 14:30:25
CURRENT_TIMESTAMP, -- 2026-06-17 14:30:25
NOW(); -- то же что CURRENT_TIMESTAMP
Извлечение частей
EXTRACT(YEAR FROM created_at) -- 2026
EXTRACT(MONTH FROM created_at) -- 6
EXTRACT(DAY FROM created_at) -- 17
EXTRACT(DOW FROM created_at) -- день недели 0-6
EXTRACT(HOUR FROM created_at) -- 14
DATE_TRUNC — округление вниз
Самая полезная функция для агрегаций:
DATE_TRUNC('day', created_at) -- 2026-06-17 00:00:00
DATE_TRUNC('week', created_at) -- начало недели (понедельник)
DATE_TRUNC('month', created_at) -- 2026-06-01
DATE_TRUNC('quarter', created_at) -- 2026-04-01
DATE_TRUNC('year', created_at) -- 2026-01-01
Выручка по месяцам:
SELECT
DATE_TRUNC('month', created_at) AS month,
SUM(amount) AS revenue
FROM orders
GROUP BY 1
ORDER BY 1;
Арифметика с датами
created_at + INTERVAL '7 days'
created_at - INTERVAL '1 month'
CURRENT_DATE - created_at -- результат INTERVAL
EXTRACT(DAY FROM CURRENT_DATE - created_at) -- N дней
Юзеры активные за 30 дней:
WHERE last_login >= CURRENT_DATE - INTERVAL '30 days'
AGE — возраст / время с события
AGE(birth_date) -- сколько лет/месяцев/дней
AGE(CURRENT_DATE, birth_date) -- то же явно
DATE_PART('year', AGE(birth_date)) -- только годы
Форматирование
TO_CHAR(created_at, 'YYYY-MM-DD') -- 2026-06-17
TO_CHAR(created_at, 'Mon DD') -- Jun 17
TO_CHAR(created_at, 'Day') -- Wednesday
TIMESTAMP vs TIMESTAMPTZ
TIMESTAMP— дата+время без timezoneTIMESTAMPTZ— с учётом timezone (рекомендуется для production)
Всегда работай в UTC в БД, конвертируй на показе:
created_at AT TIME ZONE 'Asia/Almaty'
Что важно запомнить
- Для агрегаций по дням/неделям/месяцам —
DATE_TRUNC EXTRACT(MONTH FROM ...)→ 6, ноDATE_TRUNC('month', ...)→ 2026-06-01. Второе лучше: сохраняет годCURRENT_DATE - INTERVAL '7 days'— стандарт для «за последнюю неделю»- Никогда не сравнивай
TIMESTAMPсо строкой — кастуй явно - На собеседовании: «выручка по месяцам последний год» =
DATE_TRUNC('month', ...) WHERE >= CURRENT_DATE - INTERVAL '12 months'