Passer au contenu principal
eLearner.app
Module 7 · Leçon 3 sur 427/57 dans le cours~12 min
Leçons du module (3/4)

LAG, LEAD et totaux cumulés

LAG et LEAD sont deux fonctions de fenêtre spéciales qui vous donnent accès à autres lignes de la même partition : la ligne précédente (LAG) ou la suivant (LEAD) selon le ORDER BY de la fenêtre. Ce sont les outil incontournable pour les comparaisons ligne à ligne (deltas, variations, intervalles) et - combiné avec SUM/AVG/COUNT OVER - pour les totaux cumulés.

LAG : la ligne précédente

SQL
LAG(colonna)            OVER (PARTITION BY p ORDER BY o)
LAG(colonna, n)         OVER (PARTITION BY p ORDER BY o)   -- n righe indietro
LAG(colonna, n, default) OVER (PARTITION BY p ORDER BY o)  -- default se non c'è

Exemple : pour chaque commande, "jours depuis la commande précédente du même client » :

Code
SELECT id,
       customer_id,
       ordered_at,
       ordered_at - LAG(ordered_at) OVER (
         PARTITION BY customer_id ORDER BY ordered_at
       ) AS since_previous_order
FROM   orders
ORDER BY customer_id, ordered_at;

La première commande de chaque client a since_previous_order = NULL car il n'y a pas de "précédent" dans la partition.

LEAD : la ligne suivante

Le miroir de LAG. Typique : "temps jusqu'au prochain événement", "différence avec la prochaine version".

SQL
SELECT id, ordered_at,
       LEAD(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at)
         - ordered_at AS to_next
FROM   orders;

Totaux cumulés : agrégats avec OVER

Les fonctions d'agrégation (SUM, AVG, COUNT, MAX, MIN) deviennent cumulatif en combinaison avec OVER (… ORDER BY …) :

SQL
SELECT order_id,
       total,
       SUM(total) OVER (
         PARTITION BY customer_id
         ORDER BY     ordered_at
       ) AS running_total
FROM   …;

Pour chaque ligne, SUM calcule la somme de toutes les lignes de la partition jusqu'à ce point, selon le ORDER BY de la fenêtre. Le résultat est le "balance courante" classique.

Essayez-le

Exercice#sql.m7.l3.e1
Tentatives : 0Chargement…

Pour chaque commande, affichez l'identifiant, le customer_id, la commande_at et une colonne jours_from_previous qui correspond au nombre de jours entiers (avec FLOOR) entre la commande en cours et la précédente du même client, commandée par commander_at. NULL s’il n’y a pas de commande précédente. Commandez par customer_id et commander_at.

Chargement de l'éditeur…
Afficher l'indice

LAG(ordered_at) OVER (PARTITION BY customer_id ORDER BY commander_at) renvoie l'horodatage de la commande précédente du client. Soustrayez pour obtenir un INTERVALLE, puis convertissez en jours.

Solution disponible après 3 tentatives

Exercice de révision

Exercice#sql.m7.l3.e2
Tentatives : 0Chargement…

Pour chaque commande livrée (statut = « livré »), affichez l'identifiant, le customer_id, la commande_at, la somme de la commande (somme de la quantité * le prix unitaire de ses articles) et le total cumulé (total cumulé des totaux par client, commandé par la commande_at). Utilisez un CTE pour le order_total. Commandez par customer_id et commander_at.

Chargement de l'éditeur…
Afficher l'indice

Le CTE calcule le total par commande ; le SUM OVER produit le total cumulé par client au fil du temps.

Solution disponible après 3 tentatives