Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 3 de 427/57 en el curso~12 min
Lecciones del módulo (3/4)

LAG, LEAD y totales acumulados

LAG y LEAD son dos funciones de ventana especiales que le dan acceso a otras filas de la misma partición: la fila anterior (LAG) o la el siguiente (LEAD) según el ORDER BY de la ventana. ellos son los herramienta de referencia para comparaciones fila a fila (deltas, variaciones, intervalos) y, combinado con SUM/AVG/COUNT OVER, para totales acumulados.

LAG: la fila anterior

SQL
LAG(colonna)            OVER (PARTITION BY p ORDER BY o)
LAG(colonna, n)         OVER (PARTITION BY p ORDER BY o)   -- n righe indietro
LAG(colonna, n, default) OVER (PARTITION BY p ORDER BY o)  -- default se non c'è

Ejemplo: para cada pedido, "días desde el pedido anterior por el mismo cliente":

SQL
SELECT id,
       customer_id,
       ordered_at,
       ordered_at - LAG(ordered_at) OVER (
         PARTITION BY customer_id ORDER BY ordered_at
       ) AS since_previous_order
FROM   orders
ORDER BY customer_id, ordered_at;

El primer pedido de cada cliente tiene since_previous_order = NULL porque no hay "anterior" en la partición.

PRINCIPAL: la siguiente fila

El espejo de LAG. Típico: "tiempo hasta el próximo evento", "diferencia con la próxima versión".

SQL
SELECT id, ordered_at,
       LEAD(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at)
         - ordered_at AS to_next
FROM   orders;

Totales acumulados: agregados con OVER

Las funciones agregadas (SUM, AVG, COUNT, MAX, MIN) se convierten acumulativo cuando se combina con OVER (… ORDER BY …):

SQL
SELECT order_id,
       total,
       SUM(total) OVER (
         PARTITION BY customer_id
         ORDER BY     ordered_at
       ) AS running_total
FROM   …;

Para cada fila, SUM calcula la suma de todas las filas de la partición hasta ese punto, según el ORDER BY de la ventana. El resultado es el clásico "equilibrio de carrera".

Pruébalo

Ejercicio#sql.m7.l3.e1
Intentos: 0Cargando...

Para cada pedido, muestre id, customer_id,order_at y una columna de días_desde_anterior que es el número de días completos (con FLOOR) entre el pedido actual y el anterior del mismo cliente, ordenado pororder_at. NULL si no existe ningún pedido previo. Ordene por customer_id yorder_at.

Cargando editor...
Mostrar pista

LAG(ordered_at) OVER (PARTITION BY customer_id ORDER BYorder_at) devuelve la marca de tiempo del pedido anterior del cliente. Resta para obtener un INTERVALO, luego convierte a días.

Solución disponible después de 3 intentos

Ejercicio de revisión

Ejercicio#sql.m7.l3.e2
Intentos: 0Cargando...

Para cada pedido entregado (estado = 'entregado'), muestre id, customer_id,order_at, order_total (suma de cantidad * precio unitario de sus artículos de línea) y running_total (total acumulado de los totales por cliente, ordenado pororder_at). Utilice un CTE para order_total. Ordene por customer_id yorder_at.

Cargando editor...
Mostrar pista

El CTE computa el total por pedido; SUM OVER produce el total acumulado por cliente a lo largo del tiempo.

Solución disponible después de 3 intentos