Даты и время — это не просто абстрактные цифры, а ключ к бесценной информационной части данных. В реальной жизни вы часто сталкиваетесь с датами: например, анализ продаж по месяцам, фильтрация по дате рождения сотрудников или сравнение временных интервалов. Знание, как оперировать датами, позволяет строить более гибкие запросы и делать сложные аналитические выводы.
Примеры, где работа с датами критически важна:
- Анализ продаж за конкретный месяц.
- Подсчет количества пользователей, зарегистрировавшихся за последний год.
- Построение отчетов по временным интервалам (например, ежемесячные доходы).
В PostgreSQL есть множество функций для работы с датами, и сейчас мы рассмотрим только самые полезные из них.
Основные функции для работы с датами и временем
Функция NOW() возвращает текущую дату и время для сервера базы данных. Она используется, когда вам нужно узнать точное текущее время. Пример можно представить так: вы хотите записать время создания новой записи.
SELECT NOW();
Пример результата:
2023-11-05 15:23:45.123456+00
Пример использования: Вы хотите вставить запись о заказе с текущей датой и временем:
INSERT INTO orders (order_id, order_date, total_amount)
VALUES (1, NOW(), 150.00);
Комментарий: здесь
NOW() автоматически добавит текущую дату и время в столбец
order_date.
Как именно работает оператор INSERT вы узнаете в следующих лекциях :P
Функция CURRENT_DATE
Если вам нужно только вставить текущую дату без учета времени, используйте CURRENT_DATE. Она возвращает только год, месяц и день.
Синтаксис:
SELECT CURRENT_DATE;
Пример результата:
2023-11-05
Пример использования: Допустим, вы хотите получить записи за текущий день:
SELECT *
FROM orders
WHERE order_date = CURRENT_DATE;
Комментарий: здесь мы сравниваем дату из столбца
order_date с текущей датой.
Добавим немного юмора. NOW() — это как ваш кофе на работе: готов к нему прямо сейчас. А CURRENT_DATE — это как календарь на стене: только дата, без лишних подробностей.
Извлечение частей даты с помощью DATE_PART()
Функция DATE_PART() позволяет нам получить определенную часть даты, например год, месяц, день, час или минуту. Это удобно, например, чтобы подсчитать количество заказов за определенный год или определить день недели.
Синтаксис:
DATE_PART('часть', дата)
Пример:
SELECT DATE_PART('year', NOW()) AS current_year;
Пример результата:
| current_year |
|---|
| 2025 |
Части даты, которые можно извлечь:
year: год.month: месяц.day: день.hour: час.minute: минута.second: секунда.dow: день недели (0 = воскресенье).
Пример 2: Извлечем месяц из текущей даты.
SELECT DATE_PART('month', CURRENT_DATE) AS current_month;
Результат:
| current_month |
|---|
| 6 |
Можно использовать DATE_PART() для сложных вычислений. Например:
Вы хотите выбрать только тех пользователей, которые родились в текущем году:
SELECT *
FROM students
WHERE DATE_PART('year', birth_date) = DATE_PART('year', CURRENT_DATE);
Пример результата:
| id | first_name | last_name | birth_date | grade |
|---|---|---|---|---|
| 1 | Otto | Art | 2025-03-12 | 9 |
| 2 | Anna | Pal | 2025-07-08 | 8 |
| 3 | Piu | Wolf | 2025-01-22 | 10 |
| 4 | Eva | Go | 2025-09-30 | 7 |
| 5 | Dan | Sok | 2025-06-14 | 9 |
Практические примеры
В некоторых примерах будут операторы которые вы еще не изучали. Не волнуйтесь, скоро вы будете щелкать такие примеры как орешки. Просто хочется показать вам побольше реальных примеров из жизни. Ну и заинтриговать немного :)
Пример 1: Определение возраста пользователя
Допустим, у нас есть таблица users с датой рождения каждого пользователя. Мы хотим рассчитать их возраст.
Запрос:
SELECT user_id, first_name, last_name,
DATE_PART('year', CURRENT_DATE) - DATE_PART('year', birth_date) AS age
FROM users;
Мы просто вычитаем года из текущей даты и даты рождения. Это быстрый, но не точный способ получить возраст.
Пример результата:
| user_id | first_name | last_name | age |
|---|---|---|---|
| 101 | Alex | Lin | 25 |
| 102 | Maria | Chi | 30 |
| 103 | Tor | Coz | 22 |
| 104 | Nat | Ive | 27 |
| 105 | Don | Sok | 35 |
Пример 2: Фильтрация по времени
Если вы хотите выбрать все заказы, сделанные в последний час:
SELECT *
FROM orders
WHERE order_date >= NOW() - INTERVAL '1 hour';
Заметьте, как удобно использовать INTERVAL (обозначение интервала времени).
Пример 3: Группировка по месяцам
Вы хотите подсчитать количество заказов за каждый месяц текущего года:
SELECT DATE_PART('month', order_date) AS order_month, COUNT(*) AS order_count
FROM orders
WHERE DATE_PART('year', order_date) = DATE_PART('year', CURRENT_DATE)
GROUP BY DATE_PART('month', order_date)
ORDER BY order_month;
Группировка выполняется по номеру месяца, а результат сортируется по нему же.
Пример результата:
| order_month | order_count |
|---|---|
| 1 | 120 |
| 2 | 95 |
| 3 | 134 |
| 4 | 110 |
| 5 | 42 |
Пример 4: Извлечение дня недели
Вы хотите узнать, в какой день недели сделано больше всего заказов:
SELECT DATE_PART('dow', order_date) AS day_of_week, COUNT(*) AS order_count
FROM orders
GROUP BY DATE_PART('dow', order_date)
ORDER BY order_count DESC;
Команда DATE_PART('dow') возвратит день недели для каждого заказа как число, где 0 — воскресенье, 1 — понедельник, и так далее. DOW - это сокращение от DayOfWeek - день недели.
Пример результата:
| day_of_week | order_count |
|---|---|
| 5 | 210 |
| 4 | 190 |
| 3 | 175 |
| 2 | 160 |
| 1 | 140 |
| 6 | 120 |
| 0 | 95 |
Обратите внимание на типичные ошибки
Работа с датами нередко вызывает головную боль из-за ошибок. Вот несколько распространенных проблем, с которыми вы можете столкнуться:
Формат времени и даты: когда вы используете NOW() или любую функцию, которая возвращает дату с временем, обязательно проверяйте её формат. Например, если вы сравниваете order_date с CURRENT_DATE, будьте уверены, что время игнорируется или явно указано.
Дата в строковом формате: часто в базах данных даты хранятся как строки (например, текст). Если вы попытаетесь использовать функции для работы с датами (например, DATE_PART()), то получите ошибку. Убедитесь, что данные имеют тип DATE или TIMESTAMP.
Разные временные зоны: если у вас сервер работает в одной временной зоне, а данные собираются из другой, это может привести к путанице. Рассмотрите использование временной зоны TIMESTAMPTZ.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ