SQL Window Functions: Funciones de Ventana Explicadas
¿Qué son las Window Functions?
Las funciones de ventana (window functions) realizan cálculos sobre un conjunto de filas relacionadas con la fila actual, sin agrupar los resultados en una sola fila como hace GROUP BY.
Diferencia con GROUP BY
Con GROUP BY
SELECT departamento, AVG(salario) as promedio
FROM empleados
GROUP BY departamento;
-- Resultado: 1 fila por departamento
Con Window Function
SELECT
nombre,
departamento,
salario,
AVG(salario) OVER (PARTITION BY departamento) as promedio_depto
FROM empleados;
-- Resultado: mantiene todas las filas, añade el promedio
---
Sintaxis Básica
FUNCION() OVER (
[PARTITION BY columna]
[ORDER BY columna]
[ROWS/RANGE BETWEEN ... AND ...]
)
---
Funciones de Ranking
ROW_NUMBER()
Asigna un número único secuencial:
SELECT
nombre,
departamento,
salario,
ROW_NUMBER() OVER (ORDER BY salario DESC) as ranking
FROM empleados;
| nombre | departamento | salario | ranking |
|--------|--------------|---------|---------|
| Ana | Ventas | 80000 | 1 |
| Carlos | IT | 75000 | 2 |
| María | Ventas | 75000 | 3 |
RANK()
Igual ranking para valores iguales, salta números:
SELECT
nombre,
salario,
RANK() OVER (ORDER BY salario DESC) as ranking
FROM empleados;
| nombre | salario | ranking |
|--------|---------|---------|
| Ana | 80000 | 1 |
| Carlos | 75000 | 2 |
| María | 75000 | 2 |
| Pedro | 60000 | 4 |
DENSE_RANK()
Como RANK pero sin saltar números:
SELECT
nombre,
salario,
DENSE_RANK() OVER (ORDER BY salario DESC) as ranking
FROM empleados;
| nombre | salario | ranking |
|--------|---------|---------|
| Ana | 80000 | 1 |
| Carlos | 75000 | 2 |
| María | 75000 | 2 |
| Pedro | 60000 | 3 |
NTILE(n)
Divide en n grupos iguales:
SELECT
nombre,
salario,
NTILE(4) OVER (ORDER BY salario DESC) as cuartil
FROM empleados;
---
PARTITION BY
Divide los datos en grupos independientes:
SELECT
nombre,
departamento,
salario,
ROW_NUMBER() OVER (PARTITION BY departamento ORDER BY salario DESC) as ranking_depto
FROM empleados;
| nombre | departamento | salario | ranking_depto |
|--------|--------------|---------|---------------|
| Ana | Ventas | 80000 | 1 |
| María | Ventas | 75000 | 2 |
| Carlos | IT | 75000 | 1 |
| Pedro | IT | 60000 | 2 |
---
Funciones de Agregación como Window
SELECT
fecha,
ventas,
SUM(ventas) OVER (ORDER BY fecha) as ventas_acumuladas,
AVG(ventas) OVER (ORDER BY fecha ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) as promedio_7_dias,
COUNT(*) OVER (PARTITION BY MONTH(fecha)) as ventas_mes
FROM ventas_diarias;
---
LAG y LEAD
LAG - Valor de Fila Anterior
SELECT
fecha,
ventas,
LAG(ventas, 1) OVER (ORDER BY fecha) as ventas_ayer,
ventas - LAG(ventas, 1) OVER (ORDER BY fecha) as diferencia
FROM ventas_diarias;
| fecha | ventas | ventas_ayer | diferencia |
|-------|--------|-------------|------------|
| 2024-01-01 | 100 | NULL | NULL |
| 2024-01-02 | 150 | 100 | 50 |
| 2024-01-03 | 120 | 150 | -30 |
LEAD - Valor de Fila Siguiente
SELECT
fecha,
ventas,
LEAD(ventas, 1) OVER (ORDER BY fecha) as ventas_manana
FROM ventas_diarias;
---
FIRST_VALUE y LAST_VALUE
SELECT
nombre,
departamento,
salario,
FIRST_VALUE(nombre) OVER (
PARTITION BY departamento
ORDER BY salario DESC
) as mejor_pagado_depto
FROM empleados;
---
Frame Specification (ROWS/RANGE)
Define qué filas incluir en el cálculo:
ROWS BETWEEN
SELECT
fecha,
ventas,
-- Promedio móvil de 7 días
AVG(ventas) OVER (
ORDER BY fecha
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) as promedio_7d,
-- Suma de las 3 siguientes filas
SUM(ventas) OVER (
ORDER BY fecha
ROWS BETWEEN CURRENT ROW AND 3 FOLLOWING
) as suma_proximas_3
FROM ventas_diarias;
Opciones de Frame
| Especificación | Significado |
|----------------|-------------|
| UNBOUNDED PRECEDING | Desde el inicio |
| n PRECEDING | n filas antes |
| CURRENT ROW | Fila actual |
| n FOLLOWING | n filas después |
| UNBOUNDED FOLLOWING | Hasta el final |
---
Casos de Uso Prácticos
1. Top N por Categoría
WITH ranked AS (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY categoria
ORDER BY ventas DESC
) as rn
FROM productos
)
SELECT * FROM ranked WHERE rn <= 3;
2. Porcentaje del Total
SELECT
producto,
categoria,
ventas,
ROUND(
100.0 * ventas / SUM(ventas) OVER (PARTITION BY categoria),
2
) as porcentaje_categoria,
ROUND(
100.0 * ventas / SUM(ventas) OVER (),
2
) as porcentaje_total
FROM ventas;
3. Crecimiento Mes a Mes
SELECT
mes,
ingresos,
LAG(ingresos) OVER (ORDER BY mes) as ingresos_anterior,
ROUND(
100.0 * (ingresos - LAG(ingresos) OVER (ORDER BY mes))
/ LAG(ingresos) OVER (ORDER BY mes),
2
) as crecimiento_pct
FROM ingresos_mensuales;
4. Running Total (Acumulado)
SELECT
fecha,
monto,
SUM(monto) OVER (ORDER BY fecha) as acumulado
FROM transacciones;
5. Encontrar Gaps en Secuencias
SELECT
id,
LEAD(id) OVER (ORDER BY id) as siguiente_id,
LEAD(id) OVER (ORDER BY id) - id as gap
FROM registros
HAVING gap > 1;
---
Window Functions vs Subconsultas
Con Subconsulta (menos eficiente)
SELECT
e.*,
(SELECT AVG(salario) FROM empleados WHERE departamento = e.departamento) as avg_depto
FROM empleados e;
Con Window Function (más eficiente)
SELECT
*,
AVG(salario) OVER (PARTITION BY departamento) as avg_depto
FROM empleados;
---
Múltiples Windows
Puedes definir múltiples ventanas con nombres:
SELECT
nombre,
departamento,
salario,
AVG(salario) OVER w as promedio,
MAX(salario) OVER w as maximo
FROM empleados
WINDOW w AS (PARTITION BY departamento);
---
Errores Comunes
1. ORDER BY Faltante en Ranking
-- Error: rankings inconsistentes
ROW_NUMBER() OVER ()
2. Confundir ROWS con RANGE
ROWS cuenta filas físicas, RANGE agrupa valores iguales.
3. LAST_VALUE sin Frame
-- Problema: el frame por defecto no incluye todas las filas
LAST_VALUE(x) OVER (ORDER BY y)
---
Conclusión
Las window functions son una herramienta poderosa que simplifica análisis complejos. Dominarlas te permite crear reportes avanzados con código más limpio y eficiente.
---
Tip: Usa AI2sql para generar consultas con window functions automáticamente. La IA puede ayudarte a crear análisis complejos en segundos.
Inicia tu prueba gratuita
Share this
More Articles
TOOLS
Build Your Own AI Agent Team in 15 Min — Free OpenClaw Guide
Feb 5, 2026
TOOLS
OpenClaw AI Assistant: Local 24/7 Automation Guide 2026
Feb 4, 2026
TOOLS
SQL WITH Clause (CTE): Complete Guide with Examples
Jan 14, 2026
TOOLS
MySQL to PostgreSQL Migration: Complete 2026 Guide with Syntax Conversion
Jan 14, 2026
TOOLS
SQL vs Excel: When Should You Make the Switch? [2026]
Jan 14, 2026
Copyright © AI2sql 2026
Cross Regions Technology
13553 Atlantic Blvd, Suite 201
FL 32225
Company