Skip to content
Empieza gratis

¿Por qué LAG se salta un mes que falta y cómo lo encuentro?

Descubre que LAG trae la fila anterior, no el mes anterior, y encuentra el hueco en los datos de Sur.

Curso gratis. Tu Maestro, una IA, .

En la página anterior, el cambio de julio en Sur fue -2000. Parece una baja pequeña respecto a junio. Pero la tabla no tiene junio para Sur: tiene 11 filas, no 12. ¿Contra qué se comparó julio?

Contra mayo. LAG trae la fila anterior de la partición, sin saber nada de calendarios. Si falta una fila, compara con la que sí está. Nada en el resultado te avisa: el -2000 se ve igual de confiable que los demás.

Cuidado: LAG cuenta filas, no meses

Un mes que falta no aparece como NULL: simplemente no hay fila. Antes de reportar un "cambio respecto al mes anterior", comprueba que la fila anterior de verdad sea el mes anterior.

Fila por fila

Estas son las filas de Sur de abril a agosto en la consulta de la página anterior, tal como salieron en el sandbox:

mesventasventas_anteriorcambio
2025-04-011210001127008300
2025-05-01119600121000-1400
2025-07-01117600119600-2000
2025-08-011229001176005300

Fíjate en la columna mes: de mayo salta a julio. La partición de Sur tiene 11 filas, y para LAG la fila de julio está justo debajo de la de mayo, así que mayo es "la anterior". La consulta no se equivocó: hizo exactamente lo que le pediste. La pregunta es otra.

Pedidos que llegaron más de 14 días después del anterior

Ejemplo resuelto · 3 pasos

En la tabla pedidos, queremos los pedidos que llegaron más de 14 días después del pedido anterior del mismo cliente, con las dos fechas y los días de distancia. Es el mismo problema que vas a resolver con meses, pero con días.

Piensa el siguiente paso por tu cuenta y luego ábrelo para comparar.

La forma de comprobarlo con meses es la misma: traer también el mes de la fila anterior y medir la distancia. En DuckDB, date_diff('month', inicio, fin) cuenta los meses entre dos fechas: entre mayo y julio da 2.

Inténtalo

Encuentra todas las filas donde la fila anterior de su sucursal no es el mes anterior. Necesitas dos pasos, como en el ejemplo: calcular LAG(mes) y luego filtrar. Antes, contesta la pregunta de abajo. Si no sabes cómo dividirlo en dos pasos, pregúntale a tu Maestro.

Comprueba lo que sabes: Antes de correr: ¿cuántas filas va a regresar tu consulta de huecos sobre las 35 filas de ventas_mensuales?

Regresa sucursal, mes, mesanterior (el mes de la fila anterior de su sucursal, con LAG(mes)) y mesesdedistancia (con datediff('month', mesanterior, mes)), solo para las filas donde la distancia es mayor que 1. Ordena por sucursal, mes. Terminaste cuando encuentras el hueco de Sur

Tu turno

Regresa sucursal, mes, mes_anterior (el mes de la fila anterior de su sucursal, con LAG(mes)) y meses_de_distancia (con date_diff('month', mes_anterior, mes)), solo para las filas donde la distancia es mayor que 1. Ordena por sucursal, mes. Terminaste cuando encuentras el hueco de Sur.

Tablas: ventas_mensuales (sucursal, mes, ventas)

ventas_mensuales · 35 filas

ColumnaTipo
sucursal Nombre de la sucursal: Centro, Norte o Sur.VARCHAR
mes Primer día del mes que resume la fila.DATE
ventas Ventas del mes, en pesos.BIGINT

Primeras filas

sucursalmesventas
Centro2025-01-01165100
Centro2025-02-01155700
Centro2025-03-01178700

Cada ejecución empieza con copias nuevas de las tablas del curso, así que puedes probar lo que quieras.

Listo para ejecutar tu consulta.

Ejecútalo tú

Una sola fila: julio de Sur, cuya fila anterior es mayo, a 2 meses de distancia. Y fíjate en enero: su mes_anterior es NULL, y date_diff con NULL da NULL, que no es mayor que 1. Por eso enero no sale en el resultado.

Con QUALIFY te ahorras el WITH, y además puedes usar el alias del SELECT. En el sandbox, esta versión regresó la misma fila que la solución:

SQL · línea 6
SELECT sucursal, mes,
       LAG(mes) OVER (PARTITION BY sucursal ORDER BY mes) AS mes_anterior,
       date_diff('month', mes_anterior, mes) AS meses_de_distancia
FROM ventas_mensuales
QUALIFY meses_de_distancia > 1
ORDER BY sucursal, mes;
La misma búsqueda de huecos con QUALIFY, en DuckDB.

Rellenar el calendario

Encontrar el hueco es la mitad. Si tu reporte necesita "contra el mes anterior" de verdad, la salida es darle a LAG una fila por cada mes, exista o no. Primero armas la lista completa de meses con generate_series, y después unes tus ventas con LEFT JOIN: el mes que no tiene ventas se queda con su fila y ventas en NULL.

SQL · línea 10
WITH calendario AS (
  SELECT CAST(m AS DATE) AS mes
  FROM generate_series(DATE '2025-01-01', DATE '2025-12-01',
                       INTERVAL 1 MONTH) AS t(m)
),
sur AS (
  SELECT c.mes, v.ventas
  FROM calendario c
  LEFT JOIN ventas_mensuales v
    ON v.mes = c.mes AND v.sucursal = 'Sur'
)
SELECT mes, ventas,
       LAG(ventas) OVER (ORDER BY mes) AS ventas_anterior,
       ventas - LAG(ventas) OVER (ORDER BY mes) AS cambio
FROM sur
ORDER BY mes;
Un calendario de 12 meses unido a las ventas de Sur. La condición de la sucursal va en el ON, no en el WHERE, para no perder el mes vacío.

En el sandbox, las filas de abril a agosto quedaron así:

mesventasventas_anteriorcambio
2025-04-011210001127008300
2025-05-01119600121000-1400
2025-06-01NULL119600NULL
2025-07-01117600NULLNULL
2025-08-011229001176005300

Ahora junio existe, aunque vacío, y julio ya no se compara con mayo: su cambio es NULL, que es la respuesta honesta. Si pasas v.sucursal = 'Sur' del ON al WHERE, la fila de junio se va: el WHERE corre después de la unión y descarta todo lo que no dice Sur. En el sandbox, esa versión regresó 11 filas, sin junio.

Preguntas de entrevista que esconden este hueco: "encuentra los huecos en esta serie", "¿qué usuarios dejaron de comprar más de 30 días?" o "¿qué días no hubo ninguna venta?". Las dos primeras son LAG más una distancia; la tercera es un calendario con LEFT JOIN. Si dices en voz alta que LAG cuenta filas y no fechas, ya mostraste lo que la pregunta busca. Si quieres revisar una serie tuya, cuéntale a tu Maestro cómo está tu tabla.

Antes de entregar cualquier "contra el periodo anterior", corre la búsqueda de huecos de esta página sobre tu tabla. Si sale vacía, tu LAG compara lo que dice comparar. Si sale algo, decide con quien lee el reporte: rellenar el calendario, o decir "contra mayo".

Comprueba lo que sabes: Una tienda no abrió en marzo y no hay fila de marzo. Con LAG(ventas) OVER (ORDER BY mes), ¿qué muestra la fila de abril en la columna del mes anterior?