LAG
LAG(expr, N, default) OVER ([PARTITION BY …] ORDER BY …)
Gibt den Wert eines Ausdrucks aus der Zeile N Zeilen weiter oben (standardmäßig 1) nach der Reihenfolge in OVER zurück. Für die erste Zeile gibt sie den Standardwert zurück, sonst NULL.
Parameter
- expr – der Wert, der aus der vorherigen Zeile gelesen wird.
- N – optional, wie viele Zeilen zurück. Standard ist 1.
- default – optional, der Wert, wenn es keine vorherige Zeile gibt. MySQL unterstützt ihn, MariaDB (geprüft in den Versionen 10.4 und 10.11) lehnt ihn mit einem Syntaxfehler ab – portabel IFNULL(LAG(…) OVER (…), default).
Beispiele
Die Beispiele mit den Tabellen customers, products und orders verwenden die Beispieldatenbank aus der Serie SQL-Grundlagen.
Wie viele Tage seit der vorherigen Bestellung desselben Kunden vergangen sind:
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 | +-------------+------------+------------+------+
Umsatz nach Monaten und die Änderung gegenüber dem Vormonat:
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 | +-----------+---------+------------+
Worauf Sie achten sollten
- Ohne Standardwert ist das Ergebnis für die erste Zeile NULL und die Differenz damit ebenfalls NULL – daher IFNULL() im Beispiel.
- Die Reihenfolge in OVER (ORDER BY) ist etwas anderes als die Reihenfolge des Ergebnisses – setzen Sie beide, damit die Ausgabe Sinn ergibt.
- Fensterfunktionen gibt es in MySQL ab Version 8.0 und in MariaDB ab 10.2. Das ältere MySQL 5.7 hat sie nicht.
Siehe auch:
LEAD()
OVER
DATEDIFF()