← Назад к вопросам
Какие SQL-функции работы с датами вы знаете? Приведите примеры.?
1.6 Junior🔥 241 комментариев
#SQL и базы данных
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ: SQL-функции работы с датами
Основные функции для текущей даты и времени
NOW() / CURRENT_TIMESTAMP Возвращает текущую дату и время сервера.
SELECT NOW(); -- 2026-03-26 14:35:22.123456+00
SELECT CURRENT_TIMESTAMP; -- То же самое
SELECT CURRENT_DATE; -- 2026-03-26 (только дата)
SELECT CURRENT_TIME; -- 14:35:22.123456 (только время)
CAST для типов дат
-- Преобразование строки в дату
SELECT CAST(2026-03-26 AS DATE);
SELECT CAST(2026-03-26 14:35:22 AS TIMESTAMP);
Функции для извлечения компонентов даты
EXTRACT() — получение отдельных частей даты
SELECT
EXTRACT(YEAR FROM created_at) AS year,
EXTRACT(MONTH FROM created_at) AS month,
EXTRACT(DAY FROM created_at) AS day,
EXTRACT(HOUR FROM created_at) AS hour,
EXTRACT(MINUTE FROM created_at) AS minute,
EXTRACT(SECOND FROM created_at) AS second,
EXTRACT(DOW FROM created_at) AS day_of_week, -- 0=Sunday, 1=Monday
EXTRACT(DOY FROM created_at) AS day_of_year
FROM events;
DATE_PART() — аналог EXTRACT (старый синтаксис)
SELECT DATE_PART(month, created_at) AS month;
Функции для округления и обрезания дат
DATE_TRUNC() — обрезка до указанного уровня
-- Очень полезно для группировки по периодам
SELECT
DATE_TRUNC(day, created_at)::DATE AS day,
DATE_TRUNC(month, created_at)::DATE AS month,
DATE_TRUNC(year, created_at)::DATE AS year,
DATE_TRUNC(hour, created_at) AS hour
FROM events;
-- Пример: сколько событий в день
SELECT
DATE_TRUNC(day, created_at) AS event_day,
COUNT(*) as event_count
FROM events
GROUP BY DATE_TRUNC(day, created_at)
ORDER BY event_day DESC;
Функции для арифметики с датами
INTERVAL — добавление/вычитание времени
-- Прибавить 7 дней
SELECT created_at + INTERVAL 7 days AS week_later;
-- Вычесть 30 дней
SELECT created_at - INTERVAL 30 days AS month_before;
-- Сложные интервалы
SELECT created_at + INTERVAL 1 year 2 months 3 days AS future_date;
SELECT created_at + INTERVAL 3 hours 30 minutes AS future_time;
AGE() — разница между двумя датами
-- Возраст пользователя
SELECT
user_id,
DATE_OF_BIRTH,
AGE(NOW(), DATE_OF_BIRTH) AS age
FROM users;
-- Как долго пользователь в системе
SELECT
user_id,
created_at,
AGE(NOW(), created_at) AS time_in_system
FROM users;
Прямая разница в днях/часах
-- Разница в днях
SELECT
order_id,
(delivered_at - ordered_at)::int AS delivery_days
FROM orders;
-- Разница в часах
SELECT
session_id,
EXTRACT(EPOCH FROM (end_time - start_time)) / 3600 AS session_duration_hours
FROM sessions;
Функции для форматирования дат
TO_CHAR() — преобразование даты в строку
SELECT
created_at,
TO_CHAR(created_at, YYYY-MM-DD) AS formatted_date,
TO_CHAR(created_at, DD.MM.YYYY HH24:MI:SS) AS russian_format,
TO_CHAR(created_at, Mon DD, YYYY) AS english_format,
TO_CHAR(created_at, Q) AS quarter
FROM events;
Форматы для разных локалей:
-- Американский
TO_CHAR(date, MM/DD/YYYY) -- 03/26/2026
-- Европейский
TO_CHAR(date, DD/MM/YYYY) -- 26/03/2026
-- ISO формат
TO_CHAR(date, YYYY-MM-DD) -- 2026-03-26
-- С временем
TO_CHAR(date, YYYY-MM-DD HH24:MI:SS) -- 2026-03-26 14:35:22
Функции для сравнения и фильтрации дат
BETWEEN для диапазона дат
-- События за последний месяц
SELECT * FROM events
WHERE created_at BETWEEN NOW() - INTERVAL 30 days AND NOW();
-- События в конкретный период
SELECT * FROM events
WHERE created_at BETWEEN 2026-01-01 AND 2026-03-31;
Проверка времени суток
SELECT * FROM events
WHERE EXTRACT(HOUR FROM created_at) >= 9
AND EXTRACT(HOUR FROM created_at) < 18; -- Рабочие часы
Практические примеры для Product Analyst
Пример 1: DAU (Daily Active Users)
SELECT
DATE_TRUNC(day, last_activity)::DATE AS activity_date,
COUNT(DISTINCT user_id) AS dau
FROM user_activities
WHERE last_activity >= NOW() - INTERVAL 90 days
GROUP BY DATE_TRUNC(day, last_activity)
ORDER BY activity_date DESC;
Пример 2: Когда пользователь стал активным впервые
SELECT
user_id,
MIN(DATE_TRUNC(day, created_at))::DATE AS first_active_day,
COUNT(*) AS total_events
FROM events
GROUP BY user_id;
Пример 3: Когорты по дате регистрации
SELECT
DATE_TRUNC(week, created_at)::DATE AS signup_week,
COUNT(DISTINCT user_id) AS new_users,
COUNT(DISTINCT CASE WHEN last_login >= created_at + INTERVAL 7 days
THEN user_id END) AS week1_retention
FROM users
GROUP BY DATE_TRUNC(week, created_at)
ORDER BY signup_week DESC;
Практические советы
- Всегда используй TIMESTAMPTZ в PostgreSQL для хранения дат (с timezone)
- В WHERE условиях используй INDEX для DATE_TRUNC:
CREATE INDEX ON events (DATE_TRUNC(day, created_at)) - Для GROUP BY по датам лучше GROUP BY DATE_TRUNC, а не EXTRACT
- INTERVAL полезен для динамических диапазонов дат
- TO_CHAR лучше использовать только в SELECT для вывода, не в WHERE
- Помни о timezone! Если пользователи в разных часовых поясах, это важно