SQL Pratique
Dates et heures en SQL : maîtrisez les fonctions temporelles
8 min de lecture

Dates et heures en SQL : maîtrisez les fonctions temporelles

Manipulez dates et heures en SQL comme un pro : fonctions essentielles, calculs d'intervalles et pièges à éviter pour vos entretiens data.

Avatar de Thomas LeroyThomas Leroy

La manipulation des dates est l'une des compétences les plus fréquemment testées en entretien SQL, et pourtant elle reste l'une des sources d'erreurs les plus courantes chez les candidats. Savoir extraire un mois, calculer un écart entre deux dates ou tronquer une valeur temporelle est indispensable dès qu'on travaille avec des données métier réelles : logs, transactions, inscriptions utilisateurs, événements e-commerce. Ces opérations apparaissent dans presque toutes les requêtes analytiques sérieuses.

Le problème ? Les fonctions de date varient significativement selon les moteurs SQL (PostgreSQL, MySQL, SQL Server, BigQuery). Un candidat qui ne connaît que la syntaxe d'un seul dialecte risque de bloquer face à une question formulée pour un autre environnement. Cet article vous donne les bases solides et transversales pour aborder sereinement n'importe quel exercice temporel en entretien.

📌 Ce qu'il faut retenir

  • Les fonctions de date diffèrent selon le moteur SQL, mais la logique reste identique
  • DATE_TRUNC, EXTRACT et DATEDIFF couvrent 80 % des besoins analytiques
  • Les formats de date implicites sont une source fréquente de bugs silencieux
  • Combiner fonctions temporelles et fonctions fenêtre ouvre des analyses puissantes

Pourquoi les dates posent problème en SQL

Les dates en SQL ne sont pas de simples chaînes de caractères. Elles obéissent à des types spécifiques (DATE, TIMESTAMP, DATETIME, TIME) avec leurs propres règles de comparaison et de conversion. Une date stockée en VARCHAR se comparera alphabétiquement — et donnera des résultats faux sans lever la moindre erreur.

Un deuxième problème courant : les fuseaux horaires. En PostgreSQL, TIMESTAMP WITH TIME ZONE (alias TIMESTAMPTZ) stocke l'horodatage en UTC et le convertit selon le fuseau de la session. TIMESTAMP WITHOUT TIME ZONE n'effectue aucune conversion. Ce détail peut fausser des analyses sur des données internationales si on ne le maîtrise pas.

Enfin, les noms de fonctions changent d'un moteur à l'autre. Ce qui s'appelle GETDATE() en SQL Server s'appelle NOW() ou CURRENT_TIMESTAMP en PostgreSQL et MySQL. Comprendre la logique derrière chaque opération permet de transposer rapidement d'un dialecte à l'autre.

Les fonctions essentielles à connaître

Obtenir la date et l'heure courante

Chaque moteur expose une ou plusieurs fonctions pour récupérer l'instant présent :

-- PostgreSQL / MySQL
SELECT NOW();              -- TIMESTAMP avec timezone (PG) ou local (MySQL)
SELECT CURRENT_DATE;       -- Date seule, sans heure
SELECT CURRENT_TIMESTAMP;  -- Standard SQL, équivalent à NOW()

-- SQL Server
SELECT GETDATE();          -- DATETIME local
SELECT SYSDATETIMEOFFSET(); -- avec offset timezone

-- BigQuery
SELECT CURRENT_DATE();
SELECT CURRENT_TIMESTAMP();

En entretien, précisez toujours le moteur que vous utilisez avant d'écrire votre réponse. Cela montre une maturité technique que les recruteurs apprécient.

Extraire une composante de date avec EXTRACT

EXTRACT est la fonction standard SQL pour isoler une partie d'une date (année, mois, jour, heure, minute...) :

SELECT
  EXTRACT(YEAR  FROM order_date) AS annee,
  EXTRACT(MONTH FROM order_date) AS mois,
  EXTRACT(DOW   FROM order_date) AS jour_semaine  -- 0 = dimanche en PG
FROM orders;

En SQL Server, l'équivalent est DATEPART() :

SELECT DATEPART(YEAR, order_date) AS annee;

BigQuery utilise EXTRACT avec une syntaxe proche de PostgreSQL, ce qui facilite la transposition.

Tronquer une date avec DATE_TRUNC

DATE_TRUNC arrondit une date à la granularité souhaitée. C'est l'outil de référence pour les agrégations par semaine, mois ou trimestre :

-- PostgreSQL / BigQuery
SELECT
  DATE_TRUNC('month', order_date) AS debut_mois,
  SUM(amount) AS ca_mensuel
FROM orders
GROUP BY 1
ORDER BY 1;

En SQL Server, on simule DATE_TRUNC avec DATEADD et DATEDIFF :

SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, order_date), 0) AS debut_mois;

💡 Bon à savoir

En entretien, si vous ne connaissez pas la syntaxe exacte du moteur demandé, expliquez la logique de l'opération et proposez l'équivalent que vous maîtrisez. Les recruteurs évaluent votre raisonnement autant que votre mémoire syntaxique.

Calculer des intervalles avec DATEDIFF et DATEADD

Calculer le nombre de jours entre deux dates ou décaler une date d'un intervalle donné sont des opérations omniprésentes dans les exercices analytiques.

-- PostgreSQL : soustraction directe
SELECT (end_date - start_date) AS nb_jours FROM subscriptions;

-- MySQL / SQL Server
SELECT DATEDIFF(end_date, start_date) AS nb_jours FROM subscriptions;

-- Ajouter 30 jours
SELECT DATE_ADD(start_date, INTERVAL 30 DAY);   -- MySQL
SELECT start_date + INTERVAL '30 days';          -- PostgreSQL
SELECT DATEADD(DAY, 30, start_date);             -- SQL Server

Ces fonctions sont au cœur de calculs comme la durée d'abonnement, le délai de livraison ou l'âge d'un compte utilisateur — des exemples très classiques en entretien data analyst.

Tableau comparatif des fonctions temporelles par moteur

Opération PostgreSQL MySQL SQL Server BigQuery
Date courante CURRENT_DATE CURDATE() CAST(GETDATE() AS DATE) CURRENT_DATE()
Timestamp courant NOW() NOW() GETDATE() CURRENT_TIMESTAMP()
Extraire une partie EXTRACT(part FROM date) YEAR(), MONTH(), DAY() DATEPART(part, date) EXTRACT(part FROM date)
Tronquer à un niveau DATE_TRUNC('level', date) Non natif (simulation) DATEADD + DATEDIFF DATE_TRUNC(date, level)
Différence en jours date1 - date2 DATEDIFF(d1, d2) DATEDIFF(DAY, d1, d2) DATE_DIFF(d1, d2, DAY)
Ajouter un intervalle date + INTERVAL 'n unit' DATE_ADD(date, INTERVAL n unit) DATEADD(unit, n, date) DATE_ADD(date, INTERVAL n unit)
Formater une date TO_CHAR(date, 'format') DATE_FORMAT(date, 'format') FORMAT(date, 'format') FORMAT_DATE('format', date)

Cas pratiques pour l'entretien

Calculer l'ancienneté d'un utilisateur

Un classique : déterminer depuis combien de jours ou de mois un utilisateur est inscrit.

-- PostgreSQL
SELECT
  user_id,
  created_at,
  CURRENT_DATE - created_at::DATE AS anciennete_jours,
  EXTRACT(MONTH FROM AGE(CURRENT_DATE, created_at)) AS anciennete_mois
FROM users;

La fonction AGE() de PostgreSQL retourne un intervalle lisible. En SQL Server ou MySQL, on passera par DATEDIFF.

Identifier les commandes du mois en cours

-- Universel (adaptation syntaxique selon moteur)
SELECT *
FROM orders
WHERE DATE_TRUNC('month', order_date) = DATE_TRUNC('month', CURRENT_DATE);

Cette requête est plus robuste qu'un filtre sur EXTRACT(MONTH ...) car elle tient compte de l'année. Filtrer uniquement sur le mois sans l'année retournerait les données de tous les mois de janvier, par exemple.

⚠️ Attention

Appliquer une fonction de date sur une colonne indexée (comme DATE_TRUNC(order_date)) empêche l'utilisation de l'index. Préférez filtrer avec une plage explicite : WHERE order_date >= '2026-07-01' AND order_date < '2026-08-01' pour conserver les performances.

Combiner dates et fonctions fenêtre

Combiner les fonctions temporelles avec les fonctions fenêtre SQL produit des analyses particulièrement puissantes. Par exemple, calculer le délai moyen entre 2 commandes consécutives pour chaque client :

SELECT
  user_id,
  order_date,
  LAG(order_date) OVER (PARTITION BY user_id ORDER BY order_date) AS commande_precedente,
  order_date - LAG(order_date) OVER (PARTITION BY user_id ORDER BY order_date) AS delai_jours
FROM orders;

Ce type de requête apparaît fréquemment dans les exercices sur la rétention utilisateur et les analyses de cohortes.

Regrouper par semaine ou trimestre

-- Par semaine (PostgreSQL)
SELECT
  DATE_TRUNC('week', event_date) AS semaine,
  COUNT(*) AS nb_evenements
FROM events
GROUP BY 1
ORDER BY 1;

-- Par trimestre
SELECT
  DATE_TRUNC('quarter', event_date) AS trimestre,
  SUM(revenue) AS ca
FROM orders
GROUP BY 1;

Ces agrégations temporelles sont fondamentales pour produire des rapports de performance. Maîtriser DATE_TRUNC vous fait gagner un temps précieux par rapport aux alternatives manuelles avec CASE WHEN.

Questions fréquentes

Quelle est la différence entre DATE et TIMESTAMP en SQL ?

DATE stocke uniquement la date (année, mois, jour) sans composante horaire. TIMESTAMP inclut date et heure (et parfois le fuseau selon le moteur). Pour des analyses transactionnelles où l'heure compte, préférez TIMESTAMP. Pour des dates d'anniversaire ou d'échéance, DATE suffit et simplifie les comparaisons.

Comment comparer deux dates sans se soucier de l'heure ?

Castez le timestamp en date avant la comparaison : WHERE created_at::DATE = '2026-07-14' en PostgreSQL, ou WHERE CAST(created_at AS DATE) = '2026-07-14' en syntaxe standard. Attention toutefois à l'impact sur les index (voir l'encart avertissement ci-dessus).

Pourquoi DATEDIFF retourne parfois des résultats différents selon le moteur ?

L'ordre des arguments varie. En MySQL, DATEDIFF(date_fin, date_debut) retourne un positif si date_fin > date_debut. En SQL Server, DATEDIFF(DAY, date_debut, date_fin) suit la même logique mais l'ordre est inversé. Vérifiez toujours la documentation du moteur que vous utilisez.

Comment gérer les dates NULL dans mes calculs ?

Une opération arithmétique impliquant NULL retourne toujours NULL. Utilisez COALESCE pour substituer une valeur par défaut : COALESCE(end_date, CURRENT_DATE) permet de traiter les abonnements encore actifs (sans date de fin) comme se terminant aujourd'hui.

Peut-on créer des index sur des colonnes de type TIMESTAMP ?

Oui, et c'est vivement recommandé si vous filtrez souvent sur des plages de dates. La clé est de ne pas appliquer de fonction sur la colonne dans la clause WHERE — filtrez directement sur la valeur brute ou utilisez une plage explicite pour que l'index soit effectivement utilisé par le planificateur de requêtes.

Conclusion

Les fonctions temporelles en SQL ne sont pas optionnelles pour un data analyst : elles structurent la quasi-totalité des analyses de performance, de cohorte ou de comportement utilisateur. Maîtriser EXTRACT, DATE_TRUNC, DATEDIFF et la gestion des intervalles vous place nettement au-dessus de la moyenne des candidats en entretien.

La priorité est de comprendre la logique derrière chaque opération plutôt que de mémoriser la syntaxe de chaque moteur. Une fois la logique assimilée, la transposition d'un dialecte à l'autre devient naturelle. Pour mettre en pratique ces concepts dans un environnement réel et vous préparer efficacement, explorez les exercices SQL interactifs disponibles sur SQL Pratique et testez vos requêtes directement en ligne.

Prêt à vous entraîner ?

50 exercices SQL interactifs avec éditeur en ligne, chronomètre et feedback IA.

Voir les exercices