DATEDIFF renvoie le nombre de jours, de mois ou d’autres unités entre deux dates. Chaque base de données s’y prend différemment, et les exemples couvrent PostgreSQL, MySQL, SQLite et SQL Server.
Comment utiliser DATEDIFF
DATEDIFF compte les jours, mois, années ou autres unités entre une date de début et une date de fin. Voici la version de SQL Server, celle à laquelle la plupart des gens pensent :
DATEDIFF(unit, start_date, end_date)
SELECT DATEDIFF(day, '2026-01-01', '2026-03-15');
-- Output: 73
SELECT DATEDIFF(month, '2026-01-01', '2026-03-15');
-- Output: 2
SELECT DATEDIFF(day, '2026-03-15', '2026-01-01');
-- Output: -73
L’unité peut être year, quarter, month, week, day, hour, minute, second ou plus petite. Quand la date de fin précède la date de début, le résultat est négatif.
Avec des colonnes, tu obtiens une différence par ligne :
-- Input: orders
-- order_id | order_date | ship_date
-- ---------+------------+-----------
-- 1001 | 2026-02-02 | 2026-02-04
-- 1002 | 2026-02-03 | 2026-02-10
-- 1003 | 2026-02-27 | 2026-03-02
-- 1004 | 2026-03-05 | NULL
SELECT
order_id,
order_date,
ship_date,
DATEDIFF(day, order_date, ship_date) AS fulfillment_days
FROM orders;
-- Output:
-- order_id | order_date | ship_date | fulfillment_days
-- ---------+------------+------------+-----------------
-- 1001 | 2026-02-02 | 2026-02-04 | 2
-- 1002 | 2026-02-03 | 2026-02-10 | 7
-- 1003 | 2026-02-27 | 2026-03-02 | 3
-- 1004 | 2026-03-05 | NULL | NULL
Les règles à connaître
-
Elle compte les limites franchies, pas les unités complètes.
DATEDIFF(month, ...)compte les changements de mois entre les deux dates, donc un seul jour peut compter comme un mois, voire une année :
SELECT DATEDIFF(month, '2026-01-31', '2026-02-01');
-- Output: 1
SELECT DATEDIFF(year, '2025-12-31', '2026-01-01');
-- Output: 1
-
NULL en entrée, NULL en sortie. Si l’une des dates est NULL, le résultat l’est aussi, comme pour la commande 1004 ci-dessus. Entoure l’appel de
COALESCE()si tu as besoin d’une valeur par défaut.
Syntaxes alternatives
MySQL propose un DATEDIFF à deux arguments qui ne compte que les jours et prend la date de fin en premier. Pour toute autre unité, utilise TIMESTAMPDIFF, qui prend la date de début en premier et compte des unités complètes :
SELECT DATEDIFF('2026-03-15', '2026-01-01');
-- Output: 73
SELECT TIMESTAMPDIFF(MONTH, '2026-01-01', '2026-03-15');
-- Output: 2
PostgreSQL n’a pas de DATEDIFF. Soustrais une date à une autre pour obtenir les jours. Pour des unités plus grandes, AGE() (date la plus récente en premier) renvoie un intervalle en années, mois et jours, et EXTRACT en extrait des unités complètes :
SELECT DATE '2026-03-15' - DATE '2026-01-01';
-- Output: 73
SELECT AGE('2026-03-15', '2026-01-01');
-- Output: 2 mons 14 days
SELECT EXTRACT(YEAR FROM AGE('2026-03-15', '2026-01-01')) * 12
+ EXTRACT(MONTH FROM AGE('2026-03-15', '2026-01-01'));
-- Output: 2
SQLite n’a pas de DATEDIFF non plus. julianday() transforme une date en nombre de jours, donc en soustraire deux donne la différence. CAST(... AS INTEGER) supprime la partie décimale, et comme il n’y a pas d’unité mois ou année, divise par 30 ou 365 pour une approximation :
SELECT julianday('2026-03-15') - julianday('2026-01-01');
-- Output: 73.0
SELECT CAST((julianday('2026-03-15') - julianday('2026-01-01')) / 30 AS INTEGER);
-- Output: 2
-- The time of day counts: 8 p.m. to 8 a.m. is half a day.
-- Wrap each value in date() to count calendar days instead.
SELECT julianday('2026-03-16 08:00') - julianday('2026-03-15 20:00');
-- Output: 0.5
-- A date it can't read gives NULL, so store dates as YYYY-MM-DD
SELECT julianday('03/15/2026');
-- Output: NULL
Quand utiliser DATEDIFF ?
La plupart des questions d’écart entre dates entrent dans l’un de ces quatre cas.
Mesurer une durée
Soustrais une date de début à une date de fin pour obtenir une durée : les jours nécessaires pour expédier une commande, les semaines d’un projet, les minutes d’un appel au support.
Compter les jours de retard ou restants
Compare une échéance avec aujourd’hui, ou avec une date de reporting fixe, pour voir le retard ou le temps restant. Filtre sur le signe du résultat pour ne garder qu’un côté.
Exprimer une ancienneté en mois ou en années
L’âge d’un compte, l’ancienneté d’un client ou la durée de service demandent une unité plus grande que le jour. Utilise une unité mois ou année si ta base de données en a une. Avec SQLite, divise les jours.
Trouver les lignes autour d’une date
Prends la valeur absolue de la différence pour trouver les lignes à un certain nombre de jours d’une date, avant ou après : les événements proches d’un lancement, les connexions autour d’un incident.
Exemples concrets de DATEDIFF
Vérifier les tickets de support par rapport à un SLA
Chaque ticket doit être résolu en trois jours. Compte les jours pris par chacun et signale les dépassements (SQLite) :
-- Input: support_tickets
-- ticket_id | created_at | resolved_at
-- ----------+------------+------------
-- 301 | 2026-03-02 | 2026-03-03
-- 302 | 2026-03-04 | 2026-03-07
-- 303 | 2026-03-05 | 2026-03-10
SELECT
ticket_id,
created_at,
resolved_at,
CAST(julianday(resolved_at) - julianday(created_at) AS INTEGER) AS resolution_days,
CASE
WHEN julianday(resolved_at) - julianday(created_at) <= 3 THEN 'Within SLA'
ELSE 'SLA Breach'
END AS sla_status
FROM support_tickets;
-- Output:
-- ticket_id | created_at | resolved_at | resolution_days | sla_status
-- ----------+------------+-------------+-----------------+-----------
-- 301 | 2026-03-02 | 2026-03-03 | 1 | Within SLA
-- 302 | 2026-03-04 | 2026-03-07 | 3 | Within SLA
-- 303 | 2026-03-05 | 2026-03-10 | 5 | SLA Breach
Lister les factures en retard
Affiche les factures dont l’échéance est dépassée, les plus en retard d’abord (MySQL) :
-- Input: invoices
-- invoice_id | customer | due_date
-- -----------+---------------+-----------
-- 5001 | Acme Hardware | 2026-08-15
-- 5002 | Lumen Design | 2026-09-30
-- 5003 | Acme Hardware | 2026-10-01
-- 5004 | Cedar Clinic | 2026-10-31
SELECT
invoice_id,
customer,
due_date,
DATEDIFF(CURDATE(), due_date) AS days_overdue
FROM invoices
WHERE due_date < CURDATE()
ORDER BY days_overdue DESC;
-- Output (run on 2026-10-13):
-- invoice_id | customer | due_date | days_overdue
-- -----------+---------------+------------+-------------
-- 5001 | Acme Hardware | 2026-08-15 | 59
-- 5002 | Lumen Design | 2026-09-30 | 13
-- 5003 | Acme Hardware | 2026-10-01 | 12
Grouper les clients selon leur ancienneté
Classe les clients par paliers selon leur ancienneté en années complètes (PostgreSQL) :
-- Input: customers
-- customer_name | signup_date
-- ------------------+------------
-- Northwind Traders | 2022-11-05
-- Bluebird Bakery | 2025-06-20
-- Fjord Outfitters | 2025-12-20
-- Kestrel Labs | 2026-03-02
SELECT
customer_name,
signup_date,
EXTRACT(YEAR FROM AGE(CURRENT_DATE, signup_date)) AS years_with_us,
CASE
WHEN AGE(CURRENT_DATE, signup_date) < INTERVAL '1 year' THEN 'New'
WHEN AGE(CURRENT_DATE, signup_date) < INTERVAL '2 years' THEN 'Established'
ELSE 'Loyal'
END AS customer_tier
FROM customers;
-- Output (run on 2026-10-13):
-- customer_name | signup_date | years_with_us | customer_tier
-- ------------------+-------------+---------------+--------------
-- Northwind Traders | 2022-11-05 | 3 | Loyal
-- Bluebird Bakery | 2025-06-20 | 1 | Established
-- Fjord Outfitters | 2025-12-20 | 0 | New
-- Kestrel Labs | 2026-03-02 | 0 | New
Trouver les abonnements à renouveler
Liste les abonnements qui se terminent dans les 30 prochains jours, avec les jours restants (SQL Server). La clause WHERE compare subscription_end à une plage de dates au lieu de l’entourer de DATEDIFF, pour qu’un index sur la colonne reste utilisable.
-- Input: subscriptions
-- customer_name | subscription_end
-- -----------------+-----------------
-- Harbor Dental | 2026-10-09
-- Maple Yoga | 2026-10-20
-- Orbit Analytics | 2026-11-07
-- Pinecrest Realty | 2027-01-15
SELECT
customer_name,
subscription_end,
DATEDIFF(day, GETDATE(), subscription_end) AS days_remaining
FROM subscriptions
WHERE subscription_end BETWEEN CAST(GETDATE() AS date)
AND DATEADD(day, 30, CAST(GETDATE() AS date))
ORDER BY days_remaining;
-- Output (run on 2026-10-13):
-- customer_name | subscription_end | days_remaining
-- ----------------+------------------+---------------
-- Maple Yoga | 2026-10-20 | 7
-- Orbit Analytics | 2026-11-07 | 25
Pour aller plus loin avec DATEDIFF
Sur ce blog :
-
Guide du formatage des dates en SQL : transformer des dates en texte avec
strftime,TO_CHAR,DATE_FORMATetFORMAT - Guide d’insertion de dates en SQL : les types de date et comment insérer des valeurs de date
- Comment soustraire en SQL : soustraire des nombres, des dates et des timestamps
-
Comment soustraire dans PostgreSQL : calculs sur les dates et timestamps, y compris
age() -
Les soustractions dans SQLite : écarts entre dates avec
julianday() - Extraire le total de jours, d’heures ou de minutes d’un intervalle PostgreSQL : transformer des intervalles en nombres
- Guide de COALESCE en SQL : valeurs par défaut pour les dates NULL
Documentation officielle :
- PostgreSQL : fonctions et opérateurs de date/heure
- MySQL : DATEDIFF() et TIMESTAMPDIFF()
- SQLite : fonctions de date et d’heure
- SQL Server : DATEDIFF
Beekeeper Studio est une interface de base de données gratuite & open source
Le meilleur outil de requêtes & éditeur SQL que j’aie jamais utilisé. Il m’offre tout ce dont j’ai besoin pour gérer ma base de données. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio est rapide, intuitif et facile à utiliser. Beekeeper prend en charge plein de bases de données et fonctionne parfaitement sous Windows, Mac et Linux.
Ce que les utilisateurs disent de Beekeeper Studio
« Beekeeper Studio a complètement remplacé mon ancien workflow SQL. C’est rapide, intuitif, et ça rend le travail sur les bases de données à nouveau agréable. »
« J’ai essayé beaucoup d’interfaces de base de données, mais Beekeeper trouve l’équilibre parfait entre fonctionnalités et simplicité. Ça marche, tout simplement. »