LAG
LAG(expr, N, default) OVER ([PARTITION BY …] ORDER BY …)
Renvoie la valeur de l’expression de la ligne située N lignes plus haut (par défaut 1) selon l’ordre de OVER. Pour la première ligne, renvoie la valeur par défaut, et sans elle NULL.
Paramètres
- expr – la valeur lue dans la ligne précédente.
- N – facultatif, de combien de lignes remonter. Par défaut 1.
- default – facultatif, la valeur quand il n’y a pas de ligne précédente. MySQL la prend en charge, MariaDB (vérifié en versions 10.4 et 10.11) la refuse avec une erreur de syntaxe – de façon portable IFNULL(LAG(…) OVER (…), default).
Exemples
Les exemples avec les tables customers, products et orders utilisent la base de données d’exemple de la série Bases du SQL.
Combien de jours se sont écoulés depuis la commande précédente du même client :
SELECT customer_id, order_date, LAG(order_date) OVER (PARTITION BY customer_id ORDER BY order_date, id) AS previous, DATEDIFF(order_date, LAG(order_date) OVER (PARTITION BY customer_id ORDER BY order_date, id)) AS days FROM orders WHERE customer_id IN (1, 2) ORDER BY customer_id, order_date, id;
+-------------+------------+------------+------+ | customer_id | order_date | previous | days | +-------------+------------+------------+------+ | 1 | 2026-01-05 | NULL | NULL | | 1 | 2026-01-05 | 2026-01-05 | 0 | | 1 | 2026-02-20 | 2026-01-05 | 46 | | 2 | 2026-01-12 | NULL | NULL | | 2 | 2026-03-15 | 2026-01-12 | 62 | +-------------+------------+------------+------+
Le chiffre d’affaires par mois et l’évolution par rapport au mois précédent :
SELECT month_key, revenue, revenue - IFNULL(LAG(revenue) OVER (ORDER BY month_key), 0) AS difference FROM ( SELECT EXTRACT(YEAR_MONTH FROM o.order_date) AS month_key, SUM(o.quantity * p.price) AS revenue FROM orders o JOIN products p ON p.id = o.product_id GROUP BY month_key ) x ORDER BY month_key;
+-----------+---------+------------+ | month_key | revenue | difference | +-----------+---------+------------+ | 202601 | 110.80 | 110.80 | | 202602 | 19.60 | -91.20 | | 202603 | 71.60 | 52.00 | +-----------+---------+------------+
Points d’attention
- Sans valeur par défaut, le résultat de la première ligne vaut NULL, et avec lui la différence – c’est pourquoi l’exemple utilise IFNULL().
- L’ordre dans OVER (ORDER BY) n’est pas l’ordre du résultat – réglez les deux pour que le résultat ait un sens.
- Les fonctions de fenêtrage existent dans MySQL depuis la version 8.0 et dans MariaDB depuis la 10.2. L’ancien MySQL 5.7 ne les a pas.
Voir aussi :
LEAD()
OVER
DATEDIFF()