Passer au contenu principal
eLearner.app
Module 6 · Leçon 2 sur 422/57 dans le cours~12 min
Leçons du module (2/4)

Fonctions de date et d'horodatage

Les dates et les horodatages sont partout : commandes, connexions, événements, facturation. Dans cette leçon nous voyons comment extraire des parties d'une date (année, mois…), tronquez-le à une granularité (mois, semaine…), calculez des intervalles et les différences, et faire des comparaisons entre les périodes.

Les types de bases

PostgreSQL distingue :

  • DATE — date uniquement, format YYYY-MM-DD ;
  • TIMESTAMP — date + heure, pas de fuseau horaire ;
  • TIMESTAMPTZ — date + heure + fuseau horaire ;
  • INTERVAL — un point (par exemple '3 days', '2 hours 30 minutes').

Dans notre ensemble de données ecommerce :

ColonneTapez
customers.signed_up_onDATE
orders.ordered_atTIMESTAMP
orders.shipped_atTIMESTAMP (peut être NULL)

EXTRACT — lecture d'une partie

EXTRACT(part FROM date) extrait un nombre :

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;

Les pièces les plus utilisées : YEAR, MONTH, DAY, HOUR, MINUTE, DOW (jour de la semaine 0-6), DOY (jour de l'année).

DATE_TRUNC — arrondi à l'inférieur

DATE_TRUNC('part', date) "tronque" la date à une granularité. C'est indispensable pour agréger par mois, semaine, heure :

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;

Pièces valides : 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'.

Pour des raisons de lisibilité, les gens lancent souvent un cast vers DATE lorsque le temps n'est pas nécessaire : DATE_TRUNC('month', ordered_at)::date.

Différences et intervalles

La soustraction de deux TIMESTAMP produit un INTERVAL :

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

Comparaisons avec un littéral INTERVAL :

SQL
WHERE  shipped_at - ordered_at > INTERVAL '1 day'

Ajouter des jours à une date :

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

Essayez-le

Exercice#sql.m6.l2.e1
Tentatives : 0Chargement…

Comptez combien de commandes ont été passées par an. Deux colonnes : année (entier) et order_count. Classer par année croissante.

Chargement de l'éditeur…
Afficher l'indice

EXTRACT(YEAR FROM approved_at) renvoie un NUMERIC : convertissez-le en int avec ::int pour plus de lisibilité.

Solution disponible après 3 tentatives

Exercice de révision

Exercice#sql.m6.l2.e2
Tentatives : 0Chargement…

Pour chaque mois de 2024, affichez le premier jour du mois (mois en colonne, de type date) et le nombre de commandes. Commande par mois.

Chargement de l'éditeur…
Afficher l'indice

DATE_TRUNC('month', ordonné_at) renvoie le premier jour du mois sous forme d'horodatage ; ::date le convertit en date.

Solution disponible après 3 tentatives