Imagine : tu suis les revenus de ta boîte, les ventes de ta boutique en ligne ou même juste tes propres dépenses sur l’année. Tu veux pas juste voir les revenus ou dépenses de chaque mois, mais aussi comprendre comment ça s’accumule de mois en mois.
Les fonctions d’agrégation classiques (GROUP BY) ne vont pas nous aider ici — elles regroupent les données et renvoient une ligne par groupe. Mais si on veut voir chaque mois et en même temps calculer la somme cumulée ? C’est là que SUM() avec les fonctions window entre en jeu.
Bases de l’utilisation des fonctions window pour les sommes cumulées
Les fonctions window permettent de faire des opérations d’agrégation sur des fenêtres. Grâce à ça, on peut additionner les valeurs sur chaque ligne, sans supprimer les autres lignes. Plus besoin de sacrifier des infos à cause du GROUP BY !
Syntaxe de SUM() avec une fonction window
Voici le template de base pour calculer une somme cumulée :
SELECT
column_name,
SUM(column_name) OVER (PARTITION BY partition_column ORDER BY order_column) AS cumulative_sum
FROM
table_name;
Ici :
SUM(column_name)— additionne les valeurs.OVER()— définit la fenêtre pour le calcul.PARTITION BY— sépare les données en groupes (optionnel).ORDER BY— définit l’ordre des lignes dans la fenêtre.
Exemple : revenu cumulé par mois
Imaginons une table de tes revenus :
| mois | revenu |
|---|---|
| 2023-01 | 1000 |
| 2023-02 | 1500 |
| 2023-03 | 2000 |
On veut voir le revenu de chaque mois et le total cumulé. Essayons d’écrire une requête SQL :
SELECT
mois,
revenu,
SUM(revenu) OVER (ORDER BY mois) AS revenu_cumulé
FROM
revenus;
Résultat :
| mois | revenu | revenu_cumulé |
|---|---|---|
| 2023-01 | 1000 | 1000 |
| 2023-02 | 1500 | 2500 |
| 2023-03 | 2000 | 4500 |
Ce qui se passe :
ORDER BY moisdansOVER()dit à PostgreSQL de prendre les lignes dans l’ordre chronologique.- Pour chaque ligne, la somme est calculée en prenant en compte toutes les lignes précédentes (et la ligne courante).
Réfléchis bien à ce qui se passe ici. Pour la première ligne, SUM() fait la somme de la 1ère ligne, pour la deuxième — la somme des deux premières, pour la troisième — la somme des trois. C’est pour ça que l’ordre des mois est super important !
Exemple : revenu cumulé par région
Si t’avais une table des ventes par région, une partie pourrait ressembler à ça :
| région | mois | revenu |
|---|---|---|
| Severny | 2023-01 | 1000 |
| Severny | 2023-02 | 1500 |
| Yuzhny | 2023-01 | 2000 |
| Yuzhny | 2023-02 | 2500 |
Maintenant, on veut calculer le revenu cumulé séparément pour chaque région :
SELECT
région,
mois,
revenu,
SUM(revenu) OVER (PARTITION BY région ORDER BY mois) AS revenu_cumulé
FROM
ventes;
Le résultat sera :
| région | mois | revenu | revenu_cumulé |
|---|---|---|---|
| Severny | 2023-01 | 1000 | 1000 |
| Severny | 2023-02 | 1500 | 2500 |
| Yuzhny | 2023-01 | 2000 | 2000 |
| Yuzhny | 2023-02 | 2500 | 4500 |
Maintenant chaque région est analysée séparément (PARTITION BY région), mais à l’intérieur de chaque région, les lignes sont triées par le temps (ORDER BY mois).
Moyenne glissante (AVG())
OK, les sommes cumulées c’est cool, mais si tu veux analyser les tendances, genre sur les 3 derniers mois ? Pour ça, la moyenne glissante est parfaite.
Exemple : moyenne glissante des revenus
On bosse encore avec la table revenus, et voilà ses données :
| mois | revenu |
|---|---|
| 2023-01 | 1000 |
| 2023-02 | 1500 |
| 2023-03 | 2000 |
| 2023-04 | 2500 |
La requête pour calculer la moyenne glissante sur 3 mois :
SELECT
mois,
revenu,
AVG(revenu) OVER (
ORDER BY mois
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS moyenne_glissante
FROM
revenus;
Résultat :
| mois | revenu | moyenne_glissante |
|---|---|---|
| 2023-01 | 1000 | 1000 |
| 2023-02 | 1500 | 1250 |
| 2023-03 | 2000 | 1500 |
| 2023-04 | 2500 | 2000 |
Explication :
ROWS BETWEEN 2 PRECEDING AND CURRENT ROWdit à PostgreSQL de regarder la ligne courante et les deux lignes précédentes pour calculer la moyenne.- Du coup, pour chaque mois, on voit le revenu moyen sur les 3 derniers mois.
Donc pour chaque ligne, on définit une fenêtre de 3 lignes : la courante et les deux d’avant. Et on calcule la moyenne dessus. Super pratique.
Comment marche ORDER BY et son impact
Les fonctions window dépendent de l’ordre des lignes. Si l’ordre est mauvais (ou pas défini), les résultats peuvent être chelous.
Exemple : erreurs à cause de l’absence de ORDER BY
Si on enlève ORDER BY de OVER(), au lieu d’une somme cumulée, on aura la somme totale des revenus sur chaque ligne :
SELECT
mois,
revenu,
SUM(revenu) OVER () AS mauvaise_somme_cumulée
FROM
revenus;
Résultat :
| mois | revenu | mauvaisesommecumulée |
|---|---|---|
| 2023-01 | 1000 | 7000 |
| 2023-02 | 1500 | 7000 |
| 2023-03 | 2000 | 7000 |
| 2023-04 | 2500 | 7000 |
Les lignes ne sont pas triées, et au lieu d’une somme cumulée, la fonction fait juste la somme de toutes les lignes à chaque fois.
Cas d’usage réels
Analyse des revenus :
- Les sommes cumulées permettent de suivre la croissance des ventes ou des revenus d’une boîte.
- La moyenne glissante aide à voir la tendance “pure” sans le bruit.
Modélisation financière :
Les banques et boîtes de finance utilisent les fonctions window pour analyser les paiements, la croissance des dettes et d’autres métriques.
Analyse de séries temporelles :
Les données temporelles, comme le nombre d’utilisateurs en ligne, les pages vues, le chiffre d’affaires, etc., sont parfaites à analyser avec SUM() et AVG().
GO TO FULL VERSION