Contenido de esta guía
Qué significa
LAG permite consultar un valor de una fila anterior sin perder la fila actual. Se utiliza como función de ventana y necesita una cláusula OVER. Para que «anterior» represente una secuencia reproducible, define un ORDER BY dentro de OVER; PARTITION BY puede reiniciar esa secuencia por grupos.
Qué problema resuelve
Imagina una lista de pedidos ordenada por fecha. Para calcular cuánto cambió el total respecto al pedido anterior necesitas tener ambos valores en la misma fila. LAG(total) aporta el total anterior y deja intacta la fila actual.
Pregunta principal: “anterior” solo tiene sentido si defines un orden. Sin un ORDER BY adecuado dentro de OVER, la comparación no representa una secuencia útil.
Sintaxis
LAG(expresion [, desplazamiento [, valor_inicial]])
OVER (
[PARTITION BY columna]
ORDER BY columna
)El desplazamiento predeterminado es 1. Cuando no existe una fila anterior, el resultado es NULL, salvo que indiques un valor inicial.
Ejemplo guiado
| id | fecha | total |
|---|---|---|
| 104 | 2025-05-11 | 179.0 |
| 107 | 2025-05-20 | 36.9 |
| 116 | 2025-06-12 | 999.0 |
SELECT id,
fecha,
total,
LAG(total) OVER (ORDER BY fecha, id) AS total_anterior
FROM pedidos
WHERE cliente_id = 3
ORDER BY fecha, id;| id | fecha | total | total_anterior |
|---|---|---|---|
| 104 | 2025-05-11 | 179.0 | NULL |
| 107 | 2025-05-20 | 36.9 | 179.0 |
| 116 | 2025-06-12 | 999.0 | 36.9 |
Cómo se calcula
- El
WHEREconserva los pedidos de la clienta 3. - La ventana los ordena por fecha e id.
- En la primera fila no existe un pedido anterior, por eso aparece
NULL. - Las filas siguientes reciben el total de la fila inmediatamente anterior.
Calcular una diferencia
SELECT id,
total,
total - LAG(total) OVER (ORDER BY fecha, id) AS cambio
FROM pedidos
WHERE cliente_id = 3
ORDER BY fecha, id;La primera diferencia también es NULL. No significa cero: significa que no existe un valor anterior con el que comparar.
Error frecuente
Ordenar solo la presentación
SELECT id, total,
LAG(total) OVER () AS anterior
FROM pedidos
ORDER BY fecha;El ORDER BY exterior organiza la salida, pero no define la secuencia de la ventana. PostgreSQL y SQLite pueden aceptar una ventana sin orden explícito, pero entonces las filas se procesan en un orden no especificado; SQL Server exige ORDER BY para LAG. En código portable y reproducible, colócalo dentro de OVER. Si puede haber fechas repetidas, añade una columna estable como id para resolver empates.
Comprueba lo aprendido
Compara salarios dentro de Ventas
Devuelve nombre, salario y salario_anterior para los empleados de Ventas. Usa LAG y ordena por salario e id de menor a mayor.
Solución razonada
SELECT nombre,
salario,
LAG(salario) OVER (ORDER BY salario, id) AS salario_anterior
FROM empleados
WHERE departamento = 'Ventas'
ORDER BY salario, id;Cada fila muestra el salario inmediatamente inferior dentro del conjunto filtrado. El id hace determinista el orden si dos salarios coinciden.
Compatibilidad
LAG está disponible en los motores modernos que soportan funciones de ventana, pero las versiones mínimas y los requisitos sintácticos varían. SQL Server exige ORDER BY en la cláusula OVER; PostgreSQL permite omitirlo, en cuyo caso el orden de procesamiento queda sin especificar. Para aprender una forma portable y determinista, los ejemplos de esta página usan siempre un orden explícito. La función no consulta por sí sola una “fila anterior” física almacenada en la tabla.
Qué debes recordar
LAGmira hacia filas anteriores de la ventana.- Define siempre qué significa “anterior” con
ORDER BY. - Utiliza
PARTITION BYcuando la secuencia deba reiniciarse por cliente, categoría u otro grupo. - El primer valor suele ser
NULL.
Conceptos relacionados
Fuentes técnicas consultadas
La documentación oficial se utilizó para verificar el desplazamiento, el valor predeterminado y el orden de la ventana. La redacción y los datos didácticos son propios.