Тренировка длится полтора часа, рабочий день — 8 часов, перерыв — 20 минут, а варить яйца нужно 10 минут. Всё это — о временных интервалах.
Временные интервалы полезны в реальных приложениях, когда нужно, например, рассчитать сроки выполнения задач, определить разницу между двумя датами или добавлять/вычитать время. Но прежде чем углубиться в детали, кратко вспомним, на чем мы остановились в предыдущих лекциях.
В PostgreSQL INTERVAL — это специальный тип данных, предназначенный для представления промежутков времени. В отличие от остальных временных типов, он не хранит конкретную дату или время, а описывает период, например: "2 дня", "3 часа", "5 минут".
Синтаксис INTERVAL
Интервалы можно задавать в формате:
INTERVAL 'число единицы_времени'
Примеры:
INTERVAL '2 days' -- Два дня
INTERVAL '3 hours' -- Три часа
INTERVAL '15 minutes' -- Пятнадцать минут
INTERVAL '1 day 2 hours' -- Один день и два часа
PostgreSQL поддерживает различные единицы времени: year, month, day, hour, minute, second. Вы можете комбинировать их в одном выражении.
Использование интервалов в запросах
Тип данных INTERVAL становится особенно полезным, когда вы начинаете применять его в сочетании с другими временными типами (DATE, TIMESTAMP). Давайте рассмотрим основные операции.
Добавление интервала к дате/времени
Интервалы можно добавлять к значениям даты или времени. Например:
SELECT CURRENT_DATE + INTERVAL '7 days' AS delivery_date;
-- Получаем дату через 7 дней от текущей
Результат:
| delivery_date |
|---|
| 2023-10-08 |
Вычитание интервалов из даты/времени
Кроме добавления, можно и вычитать интервалы:
SELECT NOW() - INTERVAL '2 hours' AS two_hours_ago;
-- Получаем время два часа назад
Результат:
| two_hours_ago |
|---|
| 2023-10-01 10:00:00.000 |
Вычисление разницы между двумя датами
Одной из мощных функций INTERVAL является расчет разницы между двумя датами:
SELECT '2023-10-15'::DATE - '2023-10-01'::DATE AS days_difference;
-- Сколько дней между двумя датами
Результат:
| days_difference |
|---|
| 14 days |
Обратите внимание, что результат в данном случае также представлен в виде временного интервала.
Практические примеры работы с INTERVAL
Расчет даты доставки. Представим интернет-магазин, где доставка занимает от 3 до 7 дней. Вот как можно рассчитать возможные даты доставки:
SELECT CURRENT_DATE + INTERVAL '3 days' AS earliest_delivery,
CURRENT_DATE + INTERVAL '7 days' AS latest_delivery;
Результат:
| earliest_delivery | latest_delivery |
|---|---|
| 2023-10-04 | 2023-10-08 |
Учет времени выполнения задачи. Допустим, существует таблица tasks, в которой у каждой задачи указана дата начала. Нужно рассчитать дату окончания задачи с учетом ее длительности в часах:
CREATE TABLE tasks (
task_id SERIAL PRIMARY KEY,
task_name TEXT,
start_time TIMESTAMP,
duration INTERVAL
);
INSERT INTO tasks (task_name, start_time, duration)
VALUES
('Prepare report', '2023-10-01 09:00:00', INTERVAL '4 hours'),
('Test application', '2023-10-01 10:00:00', INTERVAL '2 hours 30 minutes');
SELECT task_name,
start_time,
start_time + duration AS end_time
FROM tasks;
Результат:
| task_name | start_time | end_time |
|---|---|---|
| Prepare report | 2023-10-01 09:00:00 | 2023-10-01 13:00:00 |
| Test application | 2023-10-01 10:00:00 | 2023-10-01 12:30:00 |
Сравнение сроков выполнения. Иногда нам нужно найти все задачи, которые выполнились меньше чем за 3 часа:
SELECT task_name
FROM tasks
WHERE duration < INTERVAL '3 hours';
Результат:
| task_name |
|---|
| Test application |
Полезные трюки с интервалами
Динамическое вычисление интервалов. Можно комбинировать интервалы с другими операциями. Например, взять количество дней из столбца и преобразовать его в интервал:
SELECT CURRENT_DATE + (order_days || ' days')::INTERVAL AS order_due_date
FROM orders;
Приведение интервалов к строке. Иногда нужно привести интервал к строке для отображения:
SELECT INTERVAL '2 days 3 hours'::TEXT AS interval_text;
Результат:
| interval_text |
|---|
| 2 days 03:00:00 |
Распространенные ошибки при работе с INTERVAL
Работа с INTERVAL, несмотря на его мощь, может вызывать некоторые трудности. Одна из типичных ошибок — использование неправильного формата. Например, при попытке использовать INTERVAL '2 hours and 30 minutes', вы получите ошибку, так как PostgreSQL не понимает слов "and". Верный подход: INTERVAL '2 hours 30 minutes'.
Еще одна ошибка — забыть указать единицы времени, как в INTERVAL '2'. PostgreSQL не понимает, что это за "2", поэтому всегда старайтесь явно указывать единицы (2 days, 2 hours).
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ