Vai al contenuto
eLearner.app
Modulo 6 · Lezione 2 di 422/57 nel corso~12 min
Lezioni del modulo (2/4)

Funzioni su date e timestamp

Date e timestamp sono ovunque: ordini, login, eventi, fatturazione. In questa lezione vediamo come estrarre parti da una data (anno, mese…), troncarla a una granularità (mese, settimana…), calcolare intervalli e differenze, e fare confronti su periodi.

I tipi base

PostgreSQL distingue:

  • DATE — solo data, formato YYYY-MM-DD;
  • TIMESTAMP — data + ora, senza fuso orario;
  • TIMESTAMPTZ — data + ora + fuso orario;
  • INTERVAL — un periodo (es. '3 days', '2 hours 30 minutes').

Nel nostro dataset ecommerce:

ColonnaTipo
customers.signed_up_onDATE
orders.ordered_atTIMESTAMP
orders.shipped_atTIMESTAMP (può essere NULL)

EXTRACT — leggere una parte

EXTRACT(parte FROM data) estrae un numero:

SQL
SELECT EXTRACT(YEAR  FROM ordered_at) AS year,
       EXTRACT(MONTH FROM ordered_at) AS month,
       EXTRACT(DOW   FROM ordered_at) AS day_of_week  -- 0=domenica
FROM   orders;

Le parti più usate: YEAR, MONTH, DAY, HOUR, MINUTE, DOW (giorno settimana 0-6), DOY (giorno dell'anno).

DATE_TRUNC — arrotondare per difetto

DATE_TRUNC('parte', data) "tronca" la data a una granularità. È fondamentale per aggregare per mese, settimana, ora:

SQL
-- Tutti gli ordini fatti in "marzo 2025" cadono nello stesso bucket:
SELECT DATE_TRUNC('month', ordered_at) AS month,
       COUNT(*) AS order_count
FROM   orders
GROUP BY month
ORDER BY month;

Parti valide: 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'.

Per leggibilità si fa spesso il cast a DATE quando non serve l'ora: DATE_TRUNC('month', ordered_at)::date.

Differenze e intervalli

Sottrarre due TIMESTAMP produce un INTERVAL:

SQL
SELECT id,
       shipped_at - ordered_at AS wait_time
FROM   orders
WHERE  shipped_at IS NOT NULL;

Confronti con un letterale INTERVAL:

SQL
WHERE  shipped_at - ordered_at > INTERVAL '1 day'

Aggiungere giorni a una data:

SQL
SELECT signed_up_on + INTERVAL '30 days' AS trial_expiration
FROM   customers;

Prova tu

Esercizio#sql.m6.l2.e1
Tentativi: 0Caricamento…

Conta quanti ordini sono stati piazzati per anno. Due colonne: year (intero) e order_count. Ordina per year crescente.

Caricamento editor…
Mostra suggerimento

EXTRACT(YEAR FROM ordered_at) restituisce un NUMERIC: castalo a int con ::int per leggibilità.

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

Esercizio#sql.m6.l2.e2
Tentativi: 0Caricamento…

Per ogni mese del 2024, mostra il primo giorno del mese (colonna month, di tipo date) e il numero di ordini. Ordina per month.

Caricamento editor…
Mostra suggerimento

DATE_TRUNC('month', ordered_at) restituisce il primo giorno del mese come timestamp; ::date lo converte in date.

Soluzione disponibile dopo 3 tentativi