← Назад к вопросам

Как работать с датами в SQL (DATE_TRUNC, EXTRACT, INTERVAL)?

1.0 Junior🔥 231 комментариев
#SQL и базы данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Работа с датами в SQL

Даты — неотъемлемая часть аналитики. SQL предоставляет мощные функции для работы с временем: DATE_TRUNC для группировки, EXTRACT для выделения частей даты, INTERVAL для расчетов.

DATE_TRUNC — обрезание дат

FUNKCIYA DATE_TRUNC обрезает дату до указанной единицы времени (год, месяц, день, час и т.д.).

-- Обрезать до начала месяца
SELECT DATE_TRUNC('month', order_date) AS month_start
FROM orders;

-- Результат: 2024-01-01, 2024-02-01, 2024-03-01

-- Группировка продаж по месяцам
SELECT 
  DATE_TRUNC('month', order_date) AS month,
  COUNT(*) AS orders_count,
  SUM(amount) AS total_revenue
FROM orders
GROUP BY DATE_TRUNC('month', order_date)
ORDER BY month;

-- Группировка по неделям
SELECT 
  DATE_TRUNC('week', order_date) AS week_start,
  SUM(amount) AS weekly_revenue
FROM orders
GROUP BY DATE_TRUNC('week', order_date);

EXTRACT — извлечение части даты

EXTRACT выделяет конкретную часть даты: год, месяц, день, час, минуту и т.д.

-- Извлечение разных частей
SELECT 
  order_date,
  EXTRACT(YEAR FROM order_date) AS year,
  EXTRACT(MONTH FROM order_date) AS month,
  EXTRACT(DAY FROM order_date) AS day,
  EXTRACT(QUARTER FROM order_date) AS quarter,
  EXTRACT(DOW FROM order_date) AS day_of_week,
  EXTRACT(HOUR FROM created_at) AS hour
FROM orders;

-- Фильтр по году
SELECT * FROM orders
WHERE EXTRACT(YEAR FROM order_date) = 2024;

-- Фильтр по месяцу (независимо от года)
SELECT * FROM orders
WHERE EXTRACT(MONTH FROM order_date) IN (1, 12);  -- январь и декабрь

-- Аналитика по дню недели
SELECT 
  CASE EXTRACT(DOW FROM order_date)
    WHEN 0 THEN 'Воскресенье'
    WHEN 1 THEN 'Понедельник'
    WHEN 2 THEN 'Вторник'
    WHEN 3 THEN 'Среда'
    WHEN 4 THEN 'Четверг'
    WHEN 5 THEN 'Пятница'
    WHEN 6 THEN 'Суббота'
  END AS day_name,
  COUNT(*) AS orders_count
FROM orders
GROUP BY EXTRACT(DOW FROM order_date);

INTERVAL — операции со временем

INTERVAL добавляет или вычитает время из дат.

-- Добавить дни
SELECT 
  order_date,
  order_date + INTERVAL '7 days' AS delivery_date,
  order_date + INTERVAL '30 days' AS return_deadline
FROM orders;

-- Вычесть месяцы
SELECT 
  CURRENT_DATE - INTERVAL '3 months' AS three_months_ago;

-- Расчет времени жизни акаунта
SELECT 
  user_id,
  created_at,
  CURRENT_DATE - created_at::DATE AS days_active
FROM users;

-- Поиск событий за последние 30 дней
SELECT * FROM events
WHERE event_date >= CURRENT_DATE - INTERVAL '30 days';

-- Добавить часы
SELECT 
  created_at,
  created_at + INTERVAL '2 hours' AS deadline
FROM support_tickets;

Комбинированные примеры

Пример 1: Анализ по датам

SELECT 
  DATE_TRUNC('month', order_date)::DATE AS month,
  EXTRACT(DOW FROM order_date) AS day_of_week,
  COUNT(*) AS orders,
  SUM(amount) AS revenue
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY DATE_TRUNC('month', order_date), EXTRACT(DOW FROM order_date)
ORDER BY month DESC;

Пример 2: RFM анализ (дни с последней покупки)

SELECT 
  user_id,
  MAX(order_date) AS last_order,
  CURRENT_DATE - MAX(order_date)::DATE AS days_since_purchase,
  COUNT(*) AS total_orders
FROM orders
GROUP BY user_id
HAVING CURRENT_DATE - MAX(order_date)::DATE > 90  -- неактивны более 90 дней
ORDER BY last_order DESC;

Пример 3: Когортный анализ

SELECT 
  DATE_TRUNC('month', created_at)::DATE AS cohort_month,
  DATE_TRUNC('month', order_date)::DATE AS order_month,
  COUNT(DISTINCT user_id) AS users
FROM orders
JOIN users ON orders.user_id = users.id
GROUP BY DATE_TRUNC('month', created_at), DATE_TRUNC('month', order_date)
ORDER BY cohort_month, order_month;

Важные моменты

  • DATE_TRUNC возвращает timestamp, используй ::DATE для преобразования
  • EXTRACT возвращает число (день недели: 0-6, месяц: 1-12)
  • INTERVAL поддерживает: day, week, month, year, hour, minute, second
  • CURRENT_DATE — сегодня, CURRENT_TIMESTAMP — текущее время
  • Приводи временные зоны: AT TIME ZONE 'Europe/Moscow'

Эти функции — основа временных анализов в SQL.

Как работать с датами в SQL (DATE_TRUNC, EXTRACT, INTERVAL)? | PrepBro