Travailler avec les dates est incontournable en SQL : extractions d’indicateurs, séries temporelles, calculs de durées, reporting, etc.
📦 Types de champs date #
Types les plus courants :
| Type SQL | Description |
|---|---|
DATE |
Date seule (2024-12-31) |
TIMESTAMP / DATETIME |
Date + heure (2024-12-31 14:15:00) |
TIME |
Heure seule (14:15:00) |
DuckDB : DATE, TIME, TIMESTAMP, TIMESTAMPTZ
PostgreSQL : mêmes types
SQLite : pas de vrai type date → stockage texte, parsing manuel
📅 Formatage & parsing #
-
Conversion texte → date
SELECT TO_DATE('2024-01-01', 'YYYY-MM-DD') -- PostgreSQL -- DuckDB : on peut caster directement ou utiliser `STRPTIME` : SELECT STRPTIME('2024/01/01', '%Y/%m/%d') -
Formatage date → texte
SELECT STRFTIME(date, '%Y-%m') AS mois
🧮 Calculs sur les dates #
-
Date du jour
SELECT CURRENT_DATE; -- 2025-06-14 SELECT NOW(); -- 2025-06-14 15:32:10.123 -
Extraire une composante
-- Méthode universelle : SELECT EXTRACT(YEAR FROM date_commande) AS annee, EXTRACT(MONTH FROM date_commande) AS mois, EXTRACT(DOW FROM date_commande) AS jour_semaine FROM commandes; -- Alternatives (DuckDB / PostgreSQL) : SELECT YEAR(date_commande), MONTH(date_commande), DAY(date_commande), WEEK(date_commande) FROM commandes;DOW= Day Of Week (0 = dimanche sur PostgreSQL) -
Ajouter / soustraire un intervalle
-- DuckDB & PostgreSQL SELECT date_commande + INTERVAL '7 days' AS date_plus_7 FROM commandes; -- MySQL / SQL Server : SELECT DATE_ADD(date_commande, INTERVAL 7 DAY) -
Différence entre deux dates
-- MySQL / SQL Server : SELECT DATEDIFF('2024-01-15', '2024-01-01') -- DuckDB : SELECT DATEDIFF('day', date1, date2) -- PostgreSQL : SELECT date1 - date2 -- interval SELECT age(date1, date2) -- plus lisible -
Troncature
SELECT DATE_TRUNC('month', date_commande) AS debut_mois FROM commandes;Unité Résultat typique 'day'2024-06-14'month'2024-06-01'week'2024-06-10(début semaine)'year'2024-01-01
🧱 Générer un calendrier (calendar table) #
DuckDB / PostgreSQL :
SELECT
DATE '2024-01-01' + INTERVAL i DAY AS jour
FROM generate_series(0, 364) AS t(i);→ Crée 365 jours continus à partir du 1er janvier 2024.
🧯 Pièges classiques #
| ⚠️ Piège | ✅ Solution |
|---|---|
Comparer DATE ↔ STRING |
CAST('2024-01-01' AS DATE) |
| Manquer des jours sans données | Utiliser une table de dates pour jointure |
| Formater trop tôt les dates | Formater à la fin (TO_CHAR, FORMAT) |
| Confondre syntaxes entre moteurs SQL | Vérifier support : INTERVAL, DATEDIFF, DATEADD |
🧪 Compatibilité entre moteurs SQL (récap) #
| Objectif | DuckDB / PostgreSQL | MySQL / SQL Server |
|---|---|---|
| Ajouter une durée | + INTERVAL 1 MONTH |
DATEADD(MONTH, 1, ...) |
| Différence entre 2 dates | DATEDIFF('day', a, b) |
DATEDIFF(a, b) |
| Extraire une composante | EXTRACT(MONTH FROM date) |
MONTH(date) |
| Formater date → string | STRFTIME(date, '%Y-%m') |
DATE_FORMAT(date, ...) |
| Convertir string → date | STRPTIME / TO_DATE |
STR_TO_DATE |
🏋️♂️ Exercices #
- Extraire mois + année de chaque commande
- Calculer le nombre de jours depuis l’inscription d’un client
- Générer un calendrier 2024 + jour de semaine
- Grouper les commandes par semaine
duckdb.sql("""
SELECT
client_id,
date_commande,
YEAR(date_commande) AS annee,
MONTH(date_commande) AS mois,
date_commande + INTERVAL 7 DAY AS livraison_estimee
FROM commandes;
""").df()📚 Ressources utiles #
✅ Récap rapide #
| Objectif | DuckDB / PostgreSQL | MySQL / SQL Server |
|---|---|---|
| Ajouter une durée | + INTERVAL 1 MONTH |
DATEADD(MONTH, 1, ...) |
| Différence entre 2 dates | DATEDIFF('day', a, b) |
DATEDIFF(a, b) |
| Extraire une composante | EXTRACT(MONTH FROM date) |
MONTH(date) |
| Formater date → string | STRFTIME(date, '%Y-%m') |
DATE_FORMAT(date, ...) |
| Générer un début de mois | DATE_TRUNC('month', date) |
DATE_FORMAT(..., '%Y-%m-01') |
| Convertir string → date | STRPTIME(...), CAST(...) |
STR_TO_DATE(...) |