De ventanaestándar SQL

LAG

Toma un valor de la fila anterior para compararlo con el de la actual.

Sintaxis

LAG(<expresión>) OVER (ORDER BY <criterio de orden>)
LAG(<expresión>, <desplazamiento>, <por defecto>) OVER (ORDER BY <criterio de orden>)
LAG(<expresión>) OVER (PARTITION BY <grupo> ORDER BY <criterio de orden>)

Mira la fila de arriba en el orden indicado y devuelve un valor de ella. El desplazamiento es cuántas filas hacia atrás (1 por defecto), y el tercer argumento se usa cuando no hay fila anterior. Su contraparte, LEAD, toma el valor de la fila siguiente.

Datos para los ejemplos

orders

idcreated_atamount
12026-07-03 10:15:00120.50
22026-07-28 18:40:0080.25
32026-08-09 09:05:00199.99
42026-08-21 14:30:0045.00
52026-09-02 11:00:0064.75

Estas tablas ya están creadas en el entorno de pruebas y los ejemplos de abajo las usan. ¿Quieres repetirlo en tu propia base de datos? Copia el SQL.

El importe del pedido anterior
SELECT id, created_at, amount,
LAG(amount) OVER (ORDER BY created_at) AS previous_amount
FROM orders;
idcreated_atamountprevious_amount
12026-07-03 10:15:00120.50NULL
22026-07-28 18:40:0080.25120.50
32026-08-09 09:05:00199.9980.25
42026-08-21 14:30:0045.00199.99
52026-09-02 11:00:0064.7545.00

El primer pedido no tiene anterior, así que ahí hay NULL.

Cuánto ha cambiado el importe
SELECT id, amount,
amount - LAG(amount) OVER (ORDER BY created_at) AS difference
FROM orders;
idamountdifference
1120.50NULL
280.25-40.25
3199.99119.74
445.00-154.99
564.7519.75
El anterior y el siguiente lado a lado
SELECT id, amount,
LAG(amount) OVER (ORDER BY created_at) AS previous_amount,
LEAD(amount) OVER (ORDER BY created_at) AS next_amount
FROM orders;
idamountprevious_amountnext_amount
1120.50NULL80.25
280.25120.50199.99
3199.9980.2545.00
445.00199.9964.75
564.7545.00NULL

Ten en cuenta

Qué es la fila «anterior» lo decide el ORDER BY de OVER. Sin él, el orden es impredecible: indícalo siempre de forma explícita.

Para la primera fila el resultado es NULL, así que cualquier diferencia con ella también es NULL. Si necesitas otro valor, pasa el tercer argumento: LAG(amount, 1, 0).

LAG no se puede escribir en WHERE: obtendrás window functions are not allowed in WHERE. Calcúlalo primero en una subconsulta y filtra fuera.

Funciones relacionadas

Más detalles en el curso