Oggi ci addentriamo di nuovo nella manipolazione dei dati temporali, imparando a estrarre da essi parti specifiche (tipo anno, mese o giorno della settimana) con la funzione EXTRACT() e vediamo come calcolare l'età o gli intervalli di tempo tra date con la funzione AGE().
Lavorare con dati temporali nei progetti reali spesso richiede di isolare parti specifiche di una data o di un orario. Per esempio:
- Dividere gli ordini per anno o per mese;
- Contare quanti utenti si sono registrati in un certo giorno della settimana;
- Analizzare la durata tra due eventi.
Per risolvere questi casi usiamo le funzioni EXTRACT() e AGE().
Cos'è EXTRACT()?
La funzione EXTRACT() ti permette di tirare fuori parti specifiche di una data o di un timestamp. Ad esempio, puoi prendere l'anno da una data di nascita, trovare il numero del mese o anche estrarre il giorno della settimana.
Sintassi:
EXTRACT(part FROM source)
part: la parte della data che vuoi estrarre. Può essereYEAR,MONTH,DAY,HOUR,MINUTE,SECONDe così via.source: il tipo temporale da cui estrai l'informazione. Può essere una colonna, una costante o il risultato di una funzione.
Esempio 1: estrazione di anno, mese e giorno
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;
Risultato:
| year_part | month_part | day_part |
|---|---|---|
| 2024 | 11 | 15 |
Qui abbiamo estratto anno, mese e giorno dalla data 2024-11-15. Questo è utile quando vuoi raggruppare i dati per parti specifiche della data.
Esempio 2: giorno della settimana e ora da un orario
SELECT
EXTRACT(DOW FROM '2024-11-15'::DATE) AS day_of_week,
EXTRACT(HOUR FROM '15:30:00'::TIME) AS hour_part;
Risultato:
| day_of_week | hour_part |
|---|---|
| 3 | 15 |
DOW(Day of Week) restituisce il numero del giorno della settimana: domenica —0, lunedì —1, e così via.HOURestrae le ore da un orario.
Esempio 3: applicazione alle colonne
Se hai una tabella con delle date, puoi estrarre le parti delle date per fare analisi. Supponiamo di avere la tabella 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;
Risultato:
| order_id | month | day |
|---|---|---|
| 1 | 5 | 12 |
| 2 | 6 | 18 |
| 3 | 7 | 22 |
Cos'è AGE()?
La funzione AGE() serve per calcolare la differenza tra due timestamp. Per esempio, ti permette di calcolare l'età di un cliente in base alla sua data di nascita o vedere quanto tempo è passato da quando è stato fatto un ordine.
Sintassi:
AGE(timestamp1, timestamp2)
timestamp1: Il timestamp più recente.timestamp2: Il timestamp più vecchio.- Se passi solo un parametro, PostgreSQL lo confronta automaticamente con la data attuale (
NOW()).
Esempio 1: calcolo dell'età
SELECT AGE('2025-11-15'::DATE, '1990-05-12'::DATE) AS age;
Risultato:
| age |
|---|
| 35 years 6 mons |
Questo esempio mostra l'età di una persona nata il 12 maggio 1990, alla data del 15 novembre 2025.
Esempio 2: intervallo temporale tra eventi
SELECT AGE('2023-06-01 15:00'::TIMESTAMP, '2023-05-20 10:30'::TIMESTAMP) AS duration;
Risultato:
| duration |
|---|
| 11 days 4:30:00 |
Qui abbiamo calcolato l'intervallo di tempo tra due eventi. Utile quando vuoi sapere quanto tempo è passato tra l'inizio e la fine di un task.
Esempio 3: età del cliente
Supponiamo di avere la tabella customers:
| customer_id | birth_date |
|---|---|
| 1 | 1992-03-10 |
| 2 | 1985-07-07 |
Possiamo calcolare l'età dei clienti così:
SELECT
customer_id,
AGE(NOW(), birth_date) AS age
FROM customers;
Risultato al 13 giugno 2025:
| customer_id | age |
|---|---|
| 1 | 33 years 3 mons |
| 2 | 39 years 11 mons |
Ovviamente, tu avrai il tuo valore di NOW() e il tuo risultato.
Esempi pratici di utilizzo di EXTRACT() e AGE()
Ora mettiamo insieme queste funzioni in scenari reali.
Esempio 1: raggruppamento dati per mese
Supponiamo di avere una tabella di ordini con le date. Per contare gli ordini per mese, usa questa query:
SELECT
EXTRACT(MONTH FROM order_date) AS order_month,
COUNT(*) AS total_orders
FROM orders
GROUP BY order_month
ORDER BY order_month;
Esempio 2: giorni alla scadenza
Immagina di avere la tabella subscriptions:
| subscription_id | expiry_date |
|---|---|
| 1 | 2023-12-31 |
| 2 | 2024-05-15 |
Vogliamo sapere quanti giorni mancano alla scadenza dell'abbonamento:
SELECT
subscription_id,
AGE(expiry_date, NOW()) AS time_remaining
FROM subscriptions;
Risultato:
| subscription_id | time_remaining |
|---|---|
| 1 | 1 mons 15 days |
| 2 | 6 mons |
Errori tipici e come evitarli
Quando usi EXTRACT() e AGE() i principianti a volte inciampano in qualche trappola:
- Provare a estrarre una parte non valida, tipo i mesi da un tipo
TIME. Ricorda: le partiYEAR,MONTHeDAYfunzionano conDATE,TIMESTAMP, ma non conTIME. - Problemi con i diversi formati dei dati temporali. Ad esempio, la stringa
2023/11/15non viene considerata una data. Usa il cast con::DATEoTO_DATE(). - Differenza tra
AGE()e la sottrazione dei timestamp. Se vuoi un intervallo preciso (in mesi, giorni, secondi) — usaAGE(), mentre per il semplice numero di giorni vanno bene le operazioni aritmetiche.
Ora hai tutte le skill che ti servono per estrarre e analizzare le parti dei dati temporali in PostgreSQL. Prova a giocare con EXTRACT() e AGE() nei tuoi progetti!
GO TO FULL VERSION