Funciones de Ventana (Window Functions)
Las funciones de ventana en SQL permiten realizar cálculos sobre un subconjunto de filas relacionadas con la fila actual sin agrupar los resultados. A diferencia de las funciones de agregación tradicionales, las funciones de ventana mantienen el detalle de cada fila mientras agregan información adicional.
1. ROWNUMBER() - Numeración de Filas #
Asigna un número secuencial a cada fila dentro de una partición.
Ejemplo: #
1-- PostgreSQL, MySQL 2SELECT nombre, departamento, 3 ROW_NUMBER() OVER (PARTITION BY departamento ORDER BY salario DESC) AS ranking 4FROM empleados;
Esto numera las filas dentro de cada departamento, ordenándolas por salario descendente.
2. RANK() - Asignación de Rangos con Duplicados #
Similar a ROW_NUMBER(), pero asigna el mismo rango a valores iguales y deja huecos en la numeración.
Ejemplo: #
1-- PostgreSQL, MySQL 2SELECT nombre, departamento, salario, 3 RANK() OVER (PARTITION BY departamento ORDER BY salario DESC) AS ranking 4FROM empleados;
Si dos empleados tienen el mismo salario, recibirán el mismo rango y la numeración saltará el siguiente número.
3. DENSERANK() - Asignación de Rangos Sin Huecos #
DENSE_RANK() es similar a RANK(), pero sin huecos en la numeración.
Ejemplo: #
1-- PostgreSQL, MySQL 2SELECT nombre, departamento, salario, 3 DENSE_RANK() OVER (PARTITION BY departamento ORDER BY salario DESC) AS ranking 4FROM empleados;
Si dos empleados tienen el mismo salario, recibirán el mismo rango, pero sin dejar huecos en la numeración.
4. LAG() y LEAD() - Acceder a Filas Anteriores y Siguientes #
LAG()permite acceder a valores de filas anteriores.LEAD()permite acceder a valores de filas siguientes.
Ejemplo: #
1-- PostgreSQL, MySQL 2SELECT nombre, salario, 3 LAG(salario, 1, 0) OVER (ORDER BY salario) AS salario_anterior, 4 LEAD(salario, 1, 0) OVER (ORDER BY salario) AS salario_siguiente 5FROM empleados;
Esto devuelve el salario de la fila anterior y siguiente para cada empleado.
5. NTILE() - División en Grupos Equitativos #
Divide los resultados en un número específico de grupos.
Ejemplo: #
1-- PostgreSQL, MySQL 2SELECT nombre, salario, 3 NTILE(4) OVER (ORDER BY salario DESC) AS grupo 4FROM empleados;
Esto divide a los empleados en 4 grupos según su salario.
6. SUM(), AVG(), COUNT() con OVER() - Agregaciones sin Agrupar #
Estas funciones permiten obtener totales, promedios y conteos dentro de una partición sin perder el detalle de cada fila.
Ejemplo: #
1-- PostgreSQL, MySQL 2SELECT nombre, departamento, salario, 3 SUM(salario) OVER (PARTITION BY departamento) AS total_departamento, 4 AVG(salario) OVER (PARTITION BY departamento) AS promedio_departamento 5FROM empleados;
Esto muestra cada fila junto con el total y promedio de salarios en su departamento.
Resumen del tema
Conceptos clave #
- Cláusula
OVER(): define el marco de filas o ventana sobre el que opera la función, dividiendo por grupos conPARTITION BYy ordenando conORDER BY. - Numeración y Ranking:
ROW_NUMBER(): asigna enteros correlativos únicos sin importar duplicados.RANK(): asigna el mismo rango a empates, dejando huecos en la secuencia posterior.DENSE_RANK(): asigna el mismo rango a empates sin dejar huecos en la secuencia.
- Desplazamiento (
LAGyLEAD): acceden a valores de filas anteriores o posteriores dentro de la misma partición sin necesidad de auto-uniones (SELF JOIN). - Distribución y Agregación:
NTILE(n)distribuye filas en grupos equilibrados;SUM()oAVG()conOVER()calculan totales o promedios acumulados conservando todas las filas de detalle.
Qué debes recordar #
A diferencia de GROUP BY, las funciones de ventana calculan métricas agregadas o comparativas sin colapsar las filas de la consulta original.