Сьогодні ми знову зануримось у маніпуляції з часовими даними, навчимось витягувати з них конкретні частини (наприклад, рік, місяць або день тижня) через функцію EXTRACT() і розберемо, як рахувати вік або часові інтервали між датами через AGE().
Робота з часовими даними в реальних проєктах часто вимагає виділення конкретних частин дати чи часу. Наприклад:
- Розділення замовлень по роках або місяцях;
- Підрахунок кількості користувачів, які зареєструвались у певний день тижня;
- Аналіз тривалості часу між двома подіями.
Для таких задач юзаємо функції EXTRACT() та AGE().
Що таке EXTRACT()?
Функція EXTRACT() дозволяє витягувати конкретні частини дати або часової мітки. Наприклад, можна дістати рік із дати народження, визначити номер місяця або навіть витягти день тижня.
Синтаксис:
EXTRACT(part FROM source)
part: частина дати, яку треба витягти. Це може бутиYEAR,MONTH,DAY,HOUR,MINUTE,SECONDі т.д.source: часовий тип даних, з якого тягнемо інфу. Це може бути стовпець, константа або результат функції.
Приклад 1: витяг року, місяця і дня
SELECT
EXTRACT(YEAR FROM '2024-11-15'::DATE) AS year_part,
EXTRACT(MONTH FROM '2024-11-15'::DATE) AS month_part,
EXTRACT(DAY FROM '2024-11-15'::DATE) AS day_part;
Результат:
| year_part | month_part | day_part |
|---|---|---|
| 2024 | 11 | 15 |
Тут ми витягли рік, місяць і день із дати 2024-11-15. Такий підхід зручний, коли треба згрупувати дані по конкретних частинах дати.
Приклад 2: день тижня і година з часу
SELECT
EXTRACT(DOW FROM '2024-11-15'::DATE) AS day_of_week,
EXTRACT(HOUR FROM '15:30:00'::TIME) AS hour_part;
Результат:
| day_of_week | hour_part |
|---|---|
| 3 | 15 |
DOW(Day of Week) повертає номер дня тижня: неділя —0, понеділок —1і так далі.HOURтягне години з часу.
Приклад 3: робота зі стовпцями
Якщо у нас є таблиця з датами, можна витягати частини дат для аналізу. Наприклад, є таблиця orders:
| order_id | order_date |
|---|---|
| 1 | 2023-05-12 14:20 |
| 2 | 2023-06-18 10:45 |
| 3 | 2023-07-22 21:15 |
SELECT
order_id,
EXTRACT(MONTH FROM order_date) AS month,
EXTRACT(DAY FROM order_date) AS day
FROM orders;
Результат:
| order_id | month | day |
|---|---|---|
| 1 | 5 | 12 |
| 2 | 6 | 18 |
| 3 | 7 | 22 |
Що таке AGE()?
Функція AGE() використовується для підрахунку різниці між двома часовими мітками. Наприклад, вона дозволяє порахувати вік клієнта на основі його дати народження або дізнатись, скільки часу минуло з моменту замовлення.
Синтаксис:
AGE(timestamp1, timestamp2)
timestamp1: Пізніша часова мітка.timestamp2: Ранніша часова мітка.- Якщо вказати тільки один параметр, PostgreSQL автоматично порівняє його з поточною датою (
NOW()).
Приклад 1: підрахунок віку
SELECT AGE('2025-11-15'::DATE, '1990-05-12'::DATE) AS age;
Результат:
| age |
|---|
| 35 years 6 mons |
Цей приклад показує вік людини, яка народилась 12 травня 1990 року, на дату 15 листопада 2025 року.
Приклад 2: часовий інтервал між подіями
SELECT AGE('2023-06-01 15:00'::TIMESTAMP, '2023-05-20 10:30'::TIMESTAMP) AS duration;
Результат:
| duration |
|---|
| 11 days 4:30:00 |
Тут ми порахували часовий інтервал між двома подіями. Корисно, коли треба дізнатись, скільки часу минуло між стартом і завершенням задачі.
Приклад 3: вік клієнта
Наприклад, є таблиця customers:
| customer_id | birth_date |
|---|---|
| 1 | 1992-03-10 |
| 2 | 1985-07-07 |
Можемо порахувати вік клієнтів:
SELECT
customer_id,
AGE(NOW(), birth_date) AS age
FROM customers;
Результат на 13 червня 2025 року:
| customer_id | age |
|---|---|
| 1 | 33 years 3 mons |
| 2 | 39 years 11 mons |
Звісно, у тебе буде своє значення NOW() і свій результат.
Практичні приклади використання EXTRACT() та AGE()
Тепер об'єднуємо функції в реальних сценаріях.
Приклад 1: групування даних по місяцях
Наприклад, є таблиця замовлень з датами. Щоб порахувати замовлення по місяцях, юзаємо таку інструкцію:
SELECT
EXTRACT(MONTH FROM order_date) AS order_month,
COUNT(*) AS total_orders
FROM orders
GROUP BY order_month
ORDER BY order_month;
Приклад 2: дні до закінчення терміну
Уяви, що є таблиця subscriptions:
| subscription_id | expiry_date |
|---|---|
| 1 | 2023-12-31 |
| 2 | 2024-05-15 |
Хочемо дізнатись, скільки днів залишилось до закінчення підписки:
SELECT
subscription_id,
AGE(expiry_date, NOW()) AS time_remaining
FROM subscriptions;
Результат:
| subscription_id | time_remaining |
|---|---|
| 1 | 1 mons 15 days |
| 2 | 6 mons |
Типові граблі і як їх уникнути
Коли юзаєш EXTRACT() та AGE(), новачки іноді натикаються на підводні камені:
- Спроба витягти недопустиму частину, наприклад, місяці з типу
TIME. Запам'ятай: частиниYEAR,MONTHіDAYпрацюють зDATE,TIMESTAMP, але не зTIME. - Проблеми з різними форматами часових даних. Наприклад, рядок
2023/11/15не вважається датою. Використовуй приведення типів через::DATEабоTO_DATE(). - Різниця між
AGE()і відніманням часових міток. Якщо треба точний інтервал (у місяцях, днях, секундах) — юзайAGE(), а для простого підрахунку днів підійдуть арифметичні операції.
Тепер ти озброєний усіма потрібними навичками, щоб витягати й аналізувати частини часових даних у PostgreSQL. Спробуй погратись з EXTRACT() і AGE() у своїх проєктах!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ