Funciones de Ventana SQL — Guia Completa
Guia practica de funciones de ventana SQL: ROW_NUMBER, RANK, DENSE_RANK, LEAD, LAG, SUM, AVG sobre particiones y casos de uso de analitica real.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Overview
Las funciones de ventana en SQL calculan un valor sobre un conjunto de filas relacionadas con la fila actual — sin colapsar el resultado en grupos como GROUP BY. Desbloquean consultas analiticas potentes: totales acumulados, rankings, promedios moviles y comparaciones entre filas. Disponibles en PostgreSQL, SQL Server, MySQL 8+, Oracle y SQLite 3.25+, son esenciales para quienes escriben SQL analitico.
When to Use
- Necesitas rankings dentro de grupos (top-N por categoria)
- Se requieren totales acumulados o promedios moviles
- Quieres comparar cada fila con la anterior o siguiente
- Los agregados deben mostrarse junto a detalles de filas individuales
- Self-joins para comparaciones entre filas son demasiado complejos o lentos
Sintaxis
nombre_funcion(expresion) OVER (
[PARTITION BY expresion_particion]
[ORDER BY expresion_orden]
[clausula_marco]
)
Funciones de Ranking
| Funcion | Comportamiento | Manejo de Duplicados |
|---|---|---|
ROW_NUMBER() | Entero secuencial | Sin empates; orden arbitrario para duplicados |
RANK() | Rango con huecos | Mismo valor = mismo rango; siguiente rango salta |
DENSE_RANK() | Rango sin huecos | Mismo valor = mismo rango; siguiente rango continua |
-- Top 3 productos por ingresos en cada categoria
WITH ranked AS (
SELECT
product_id,
category,
revenue,
RANK() OVER (PARTITION BY category ORDER BY revenue DESC) as rank
FROM product_revenue
)
SELECT * FROM ranked WHERE rank <= 3;
Funciones de Desplazamiento
-- Comparar mes actual con mes anterior
SELECT
month,
revenue,
LAG(revenue) OVER (ORDER BY month) as prev_month_revenue,
revenue - LAG(revenue) OVER (ORDER BY month) as month_over_month_change,
LEAD(revenue) OVER (ORDER BY month) as next_month_revenue
FROM monthly_revenue;
Funciones de Ventana Agregadas
-- Total acumulado y promedio movil
SELECT
order_id,
order_date,
amount,
SUM(amount) OVER (ORDER BY order_date) as running_total,
AVG(amount) OVER (
ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) as seven_day_avg
FROM orders;
Clausulas de Marco
| Marco | Significado |
|---|---|
ROWS UNBOUNDED PRECEDING | Todas las filas desde el inicio hasta la actual |
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING | Fila actual mas una a cada lado |
RANGE BETWEEN INTERVAL '7 days' PRECEDING AND CURRENT ROW | Ventana basada en tiempo |
Ejemplos del Mundo Real
Deduplicacion
-- Mantener el registro mas reciente por cliente
WITH ranked AS (
SELECT
customer_id,
email,
updated_at,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY updated_at DESC) as rn
FROM customer_profiles
)
SELECT customer_id, email, updated_at FROM ranked WHERE rn = 1;
Calculo de Percentil
SELECT
employee_id,
department,
salary,
NTILE(4) OVER (PARTITION BY department ORDER BY salary) as quartile,
PERCENT_RANK() OVER (PARTITION BY department ORDER BY salary) as percentile
FROM employees;
Common Mistakes
- Olvidar
PARTITION BY— la ventana se aplica a todo el resultado en lugar de grupos - Usar
GROUP BYcon funciones de ventana — operan en niveles conceptuales diferentes; combinar con CTEs - Confundir
RANKyROW_NUMBER— usarROW_NUMBERpara deduplicacion,RANKpara analisis por niveles - Marcos de ventana en datos desordenados — siempre especificar
ORDER BYdentro deOVER() - Rendimiento en grandes datasets — asegurar que las columnas de
PARTITION BYyORDER BYesten indexadas
FAQ
Las funciones de ventana estan disponibles en MySQL? Si, a partir de MySQL 8.0. MariaDB 10.2+ tambien las soporta.
Puedo usar multiples funciones de ventana en una consulta?
Si. Tambien puedes definir una ventana nombrada para reutilizar: WINDOW w AS (PARTITION BY dept ORDER BY salary).
Funcionan con DISTINCT?
DISTINCT se aplica despues de funciones de ventana. Usa una subconsulta o CTE si necesitas resultados distintos con calculos de ventana.
Recursos Relacionados
SQL CTEs — Common Table Expressions Explained
A practical guide to SQL Common Table Expressions (CTEs): non-recursive and recursive CTEs, readability, performance, and when to use them over subqueries.
GuideSQL Performance Tuning — Indexes, Queries, and Explain Plans
A practical guide to optimizing SQL queries: indexing strategies, query rewriting, EXPLAIN plan analysis, and common anti-patterns to avoid.
GuideSQL Joins — Visual Guide with Examples
A visual guide to SQL joins: INNER, LEFT, RIGHT, FULL OUTER, CROSS, and SELF joins with practical examples, performance tips, and common pitfalls.