Resolver problemas analíticos complejos en SQL sin recurrir a múltiples subconsultas anidadas o CTEs encadenadas es posible gracias a las window functions. Estas funciones permiten calcular rankings, comparar periodos, obtener acumulados y porcentajes, todo dentro de una sola consulta. Dominarlas marca la diferencia entre escribir SQL operacional y SQL verdaderamente analítico.
¿Qué son las window functions y por qué reemplazan subconsultas complejas?
Una window function opera sobre un conjunto de filas relacionadas con la fila actual, pero sin colapsar el resultado como lo hace GROUP BY [0:25]. La clave está en la cláusula OVER(), que define la ventana de cálculo.
Dentro de OVER() se combinan dos elementos fundamentales:
- PARTITION BY: define el grupo dentro del cual se realiza el cálculo, equivalente a un
GROUP BY pero conservando todas las filas.
- ORDER BY: establece el orden dentro de cada partición.
Esto significa que puedes asignar un ranking a cada pedido por cliente sin perder el detalle de cada fila [1:07]. Por ejemplo, al ejecutar ROW_NUMBER() OVER(PARTITION BY cliente ORDER BY fecha_pedido), cada fila recibe un número secuencial dentro de su grupo, sin que las filas se colapsen.
¿Cómo se construye un ranking por producto con OVER?
El proceso es directo: primero se crea una partición con PARTITION BY, se ordena con ORDER BY y se aplica la función de ranking [1:25]. En el ejemplo de la clase, se generan dos rankings distintos en la misma consulta: uno por número de pedido y otro por producto, ambos usando OVER(PARTITION BY ... ORDER BY ... DESC). Lo que antes requería cuatro subconsultas o varias CTEs, se resuelve con dos líneas de window functions [2:30].
Un detalle importante al trabajar en SQL Server: hay que verificar que la base de datos activa sea la correcta. Si el selector indica Master en lugar de la base deseada, la consulta fallará [2:00].
¿Cómo obtener el top tres de categorías con más pedidos?
Combinando una CTE (Common Table Expression) con una window function, el resultado es limpio y eficiente [2:50]. Se define un WITH que contiene la consulta con RANK() OVER(PARTITION BY ...), y luego se filtra con un simple SELECT donde el ranking sea menor o igual a tres. Dos pasos en lugar de múltiples subconsultas anidadas.
¿Para qué sirven las funciones LAG y LEAD en análisis temporal?
LAG accede al valor de la fila anterior y LEAD al de la fila siguiente dentro de la partición [3:30]. Si pensamos en una hoja de cálculo, LAG trae el dato de la celda de arriba y LEAD el de la celda de abajo. Su uso principal es calcular variaciones entre periodos.
El ejemplo práctico calcula el crecimiento mes a mes por país [3:55]:
- Se obtiene el total de ventas del mes actual.
- Con
LAG(ventas) OVER(PARTITION BY pais ORDER BY año, mes) se recuperan las ventas del mes anterior.
- La diferencia absoluta se calcula restando ambos valores.
- El porcentaje de crecimiento se deriva de esa diferencia.
Cuando no existen datos del periodo anterior, el resultado muestra NULL, lo cual es correcto y esperado [4:40].
¿Cómo calcular acumulados y porcentajes con SUM OVER?
La función SUM() OVER() permite manejar totales acumulados y globales en una misma consulta [5:15]. El ejemplo construye una tabla de frecuencia acumulada por país:
- Ventas por país: suma de ventas agrupada por cada país.
- Total global:
SUM(total) OVER() sin partición, que devuelve el total general.
- Acumulado en el ranking:
SUM(total) OVER(ORDER BY total DESC) que va sumando progresivamente.
- Porcentaje del total: se obtiene con un
CAST para calcular la proporción acumulada [5:50].
El resultado es una tabla de frecuencia acumulada que muestra cuánto representa cada país respecto al total y en qué posición del ranking se encuentra.
¿Cuál es el desafío práctico con LAG y RANK?
El reto propuesto tiene dos partes:
- Calcular el crecimiento de ventas mes a mes para Argentina en 2024 usando LAG, mostrando mes, ventas actuales, ventas anteriores, diferencia absoluta y porcentaje.
- Usar
ROW_NUMBER o RANK para identificar los cinco mejores meses de ventas de Argentina con su posición en el ranking histórico.
Comparte tu script y resultado para poner en práctica estas funciones que transforman la forma de analizar datos con SQL.