LAG() în MySQL

Valoarea din rândul anterior (sau cu N rânduri înainte), ca să compari cu perioada trecută.

Sintaxă
LAG(expresie[, n[, implicit]]) OVER ([PARTITION BY ...] ORDER BY ...)

Ce face LAG()

LAG() „se uită înapoi” în ordinea dată de ORDER BY. Este folosită pentru comparații de tipul „luna aceasta față de luna trecută”. Pentru primul rând nu există valoare anterioară, așa că rezultatul este NULL sau valoarea implicită dată.

Parametri

Parametru Descriere
expresie Valoarea citită din rândul anterior.
n Opțional. Cu câte rânduri în urmă (implicit 1).
implicit Opțional. Valoarea când nu există rând anterior.

Ce returnează

Valoarea din rândul anterior.

Exemple

Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.

CREATE TABLE vanzari (
  agent VARCHAR(20),
  oras VARCHAR(20),
  luna INT,
  suma INT
);

INSERT INTO vanzari VALUES
  ('Ana', 'Iași', 1, 1200), ('Ana', 'Iași', 2, 1500), ('Ana', 'Iași', 3, 900),
  ('Dan', 'Cluj', 1, 900), ('Dan', 'Cluj', 2, 900), ('Dan', 'Cluj', 3, 1700),
  ('Ioana', 'Iași', 1, 2000), ('Ioana', 'Iași', 2, 1100);

Exemplul 1: Creșterea față de luna trecută

SELECT agent, luna, suma,
       LAG(suma) OVER (PARTITION BY agent ORDER BY luna) AS luna_trecuta,
       suma - LAG(suma) OVER (PARTITION BY agent ORDER BY luna) AS diferenta
FROM vanzari
ORDER BY agent, luna;

Rezultat

+-------+------+------+--------------+-----------+
| agent | luna | suma | luna_trecuta | diferenta |
+-------+------+------+--------------+-----------+
| Ana   |    1 | 1200 |         NULL |      NULL |
| Ana   |    2 | 1500 |         1200 |       300 |
| Ana   |    3 |  900 |         1500 |      -600 |
| Dan   |    1 |  900 |         NULL |      NULL |
| Dan   |    2 |  900 |          900 |         0 |
| Dan   |    3 | 1700 |          900 |       800 |
| Ioana |    1 | 2000 |         NULL |      NULL |
| Ioana |    2 | 1100 |         2000 |      -900 |
+-------+------+------+--------------+-----------+

Exemplul 2: Valoare implicită pentru primul rând

SELECT agent, luna, suma, LAG(suma, 1, 0) OVER (PARTITION BY agent ORDER BY luna) AS anterior
FROM vanzari
WHERE agent = 'Ana'
ORDER BY luna;

Rezultat

+-------+------+------+----------+
| agent | luna | suma | anterior |
+-------+------+------+----------+
| Ana   |    1 | 1200 |        0 |
| Ana   |    2 | 1500 |     1200 |
| Ana   |    3 |  900 |     1500 |
+-------+------+------+----------+

Greșeli frecvente

  • Uiți PARTITION BY și compari prima lună a unui agent cu ultima lună a agentului anterior.

Comenzi înrudite

  • LEAD(): Valoarea din rândul următor (sau cu N rânduri înainte în ordine).
  • FIRST_VALUE(): Prima valoare din fereastră, de exemplu prima lună a fiecărui agent.
  • ROW_NUMBER(): Numerotează rândurile 1, 2, 3… în fiecare grup, fără să le comprime ca GROUP BY.