Modelado físico avanzado relacional de bases de datos

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. ROW_NUMBER() - 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. DENSE_RANK() - 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.