← Guides

Fonctions de date SQL : regrouper par mois, filtrer une période et comparer les années

Chiffre d'affaires mensuel, filtre sur les 30 derniers jours et comparaison d'une année sur l'autre en PostgreSQL, MySQL et SQL Server, avec l'erreur qui désactive les index.

SQL · 8 min de lecture

Par l'équipe éditoriale FormulAI · Relu en octobre 2026

Regrouper le CA par mois

Chaque moteur a sa fonction pour tronquer une date : DATE_TRUNC en PostgreSQL, DATE_FORMAT en MySQL, DATEFROMPARTS ou FORMAT en SQL Server. Tronquer au premier jour du mois garde un résultat triable comme une vraie date.

-- PostgreSQL
SELECT DATE_TRUNC('month', cree_le) AS mois,
       SUM(montant) AS ca
FROM commandes
GROUP BY 1
ORDER BY 1;

-- MySQL
SELECT DATE_FORMAT(cree_le, '%Y-%m-01') AS mois, SUM(montant)
FROM commandes GROUP BY mois ORDER BY mois;

Filtrer une période sans casser l'index

Écrire WHERE YEAR(cree_le) = 2025 applique une fonction à chaque ligne : la base ne peut plus utiliser l'index et parcourt toute la table. Utilisez un intervalle semi-ouvert, compatible avec l'index et correct même avec des heures.

SELECT *
FROM commandes
WHERE cree_le >= '2025-01-01'
  AND cree_le <  '2026-01-01';

Les 30 derniers jours

Utilisez la date courante de votre moteur : CURRENT_DATE - INTERVAL '30 days' en PostgreSQL, CURDATE() - INTERVAL 30 DAY en MySQL, DATEADD(day, -30, GETDATE()) en SQL Server. Décidez si « 30 jours » inclut aujourd'hui : finance et tableaux de bord divergent souvent, et l'écart se voit dans les totaux.

Comparer avec l'année précédente

Agrégez d'abord par mois, puis utilisez LAG avec un décalage de 12 pour récupérer le même mois de l'année précédente. Pas d'auto-jointure, et le taux de croissance en une passe. NULLIF évite la division par zéro pour les nouveaux produits.

WITH m AS (
  SELECT DATE_TRUNC('month', cree_le) AS mois, SUM(montant) AS ca
  FROM commandes GROUP BY 1
)
SELECT mois, ca,
       LAG(ca, 12) OVER (ORDER BY mois) AS ca_n_1,
       ROUND(100.0 * (ca - LAG(ca, 12) OVER (ORDER BY mois))
             / NULLIF(LAG(ca, 12) OVER (ORDER BY mois), 0), 1) AS croissance_pct
FROM m
ORDER BY mois;

Les mois sans vente

GROUP BY ne renvoie que les mois qui ont des lignes : un mois à zéro disparaît du graphique. Générez un calendrier (generate_series en PostgreSQL, CTE récursive ailleurs) et faites un LEFT JOIN de vos agrégats avec COALESCE(ca, 0). Pensez aussi aux fuseaux : stockez en UTC et convertissez avec AT TIME ZONE avant de tronquer si le rapport est local.

Comment ce guide a été réalisé

Chaque formule, requête et script de ce guide a été exécuté sur un vrai fichier d'exemple (Excel 365, Google Sheets, PostgreSQL, MySQL ou Python 3) avant publication. Nous documentons les cas limites rencontrés pendant les tests : nombres stockés en texte, mois vides, valeurs NULL. L'IA nous aide à rédiger et traduire ; une personne vérifie chaque exemple et met le guide à jour quand les logiciels évoluent. Une erreur ? Écrivez à contact@formulai-app.com.