Guía Completa de Funciones de Ventana en SQL

Última actualización: junio 25, 2026
  • Permiten realizar cálculos agregados y analíticos manteniendo la identidad de cada fila individual.
  • Se definen mediante la cláusula OVER, que establece el marco de filas sobre el cual opera la función.
  • Facilitan tareas avanzadas como el cálculo de sumas acumuladas, rankings complejos y comparativas temporales.

Funciones de ventana SQL

Si alguna vez has sentido que el clásico GROUP BY se te queda corto para ciertos análisis, es muy probable que necesites dar el salto a las funciones de ventana. A menudo, cuando empezamos en el mundo de las bases de datos, creemos que para sumar o promediar datos obligatoriamente tenemos que agrupar las filas y perder el detalle individual, pero las funciones de ventana rompen esa limitación permitiéndonos hacer cálculos complejos mientras mantenemos cada registro intacto.

Básicamente, estas herramientas operan sobre un conjunto de filas relacionadas con la fila actual, lo que en el argot técnico llamamos marco de ventana o ventana deslizante. Olvídate de confusiones con sistemas operativos; aquí hablamos de una capacidad analítica brutal que te permite comparar una fila con la anterior, crear rankings o sacar totales acumulados sin tener que recurrir a complicadas subconsultas o self-joins que solo ralentizan el sistema.

solución de integración de datos
Related article:
Solución de integración de datos: guía completa para empresas

¿Qué es exactamente una ventana en SQL?

Para entenderlo de forma sencilla, imagina que la función no mira la tabla entera como un bloque, sino que se desplaza fila por fila. Una ventana es ese grupo de registros vinculados a la fila actual que se utilizan para ejecutar la operación. Por ejemplo, si quieres calcular cuánto se ha vendido hasta hoy, la ventana incluirá la fila de hoy y todas las anteriores, moviéndose conforme avanzamos en la lista.

A lo largo de la historia, estas funciones han ido aterrizando en los distintos motores. Aunque Oracle las presentó ya en 1998 con su versión 8i, no fue hasta el estándar SQL:2003 que se formalizaron. Desde entonces, SQL Server, PostgreSQL, MariaDB y MySQL han adoptado esta potencia, aunque curiosamente no suelen enseñarse en los cursos básicos, lo que te da una ventaja competitiva si logras dominarlas.

Desglosando la sintaxis: El corazón de OVER()

Para que una función se comporte como una función de ventana, es imprescindible el uso de la cláusula OVER(). Sin ella, el motor de la base de datos interpretará que estás intentando hacer una agregación normal. La estructura básica se compone de la función deseada seguida de OVER, donde definimos cómo queremos que se comporte el cálculo.

Related article:
Integración de bases de datos con Spyder Python IDE: un enfoque práctico

Dentro de los paréntesis de OVER, tenemos tres piezas fundamentales. Primero, PARTITION BY, que sirve para dividir los datos en grupos más pequeños (particiones) basándose en una columna; si no lo pones, toda la tabla se trata como una única partición. Segundo, ORDER BY, que establece la secuencia en la que se procesan las filas, algo vital para sumas acumuladas o rankings. Y tercero, el marco de ventana, que delimita exactamente qué filas entran en la cuenta.

Cuando hablamos del marco de ventana, entran en juego las cláusulas ROWS y RANGE. Mientras que ROWS se basa estrictamente en el número de filas (por ejemplo, las dos anteriores y la actual), RANGE tiene en cuenta los valores de las columnas. Los límites pueden ser UNBOUNDED PRECEDING para abarcar todo desde el inicio, o CURRENT ROW para detenerse en la fila donde estamos posicionados.

Categorías de funciones y sus usos prácticos

Podemos clasificar estas herramientas en tres grandes grupos según el resultado que busquemos. El primero son las de agregación, como SUM(), AVG(), COUNT(), MIN() y MAX(). A diferencia de su versión estándar, aquí puedes ver, por ejemplo, la venta de un producto y, justo al lado, el promedio de ventas de toda su categoría sin que la tabla se colapse en una sola línea.

Fundamentos de Pandas para Ciencia de Datos
Related article:
Guía Completa de Fundamentos de Pandas para Ciencia de Datos

El segundo grupo es el de clasificación o ranking. Aquí destacan ROW_NUMBER(), que asigna un número único secuencial; RANK(), que deja huecos si hay empates (1, 2, 2, 4); y DENSE_RANK(), que mantiene la secuencia sin saltarse números (1, 2, 2, 3). También tenemos NTILE(), que es fantástica para dividir los datos en percentiles o cuartiles, ideal para segmentar clientes en grupos de valor.

Por último, tenemos las funciones analíticas o de valor. LAG() nos permite mirar hacia atrás y traer el valor de una fila anterior, mientras que LEAD() hace lo contrario, mirando hacia adelante. Estas son la joya de la corona para analizar series temporales, ya que permiten calcular variaciones porcentuales o diferencias entre trimestres de forma extremadamente limpia.

Ejemplos reales aplicados al análisis de datos

Imagina que trabajas con un catálogo de álbumes y quieres saber cuánto contribuye cada disco a las ventas totales de su género. Usando SUM(copies_sold) OVER(PARTITION BY album_genre), obtienes el total del género en cada fila y luego simplemente divides la venta individual por ese total para sacar el porcentaje. Es una forma elegantísima de analizar la cuota de mercado interna.

Otro caso típico es el de las sumas acumuladas. Si quieres ver cómo crecen las ventas de un artista mes a mes, basta con usar SUM() con un ORDER BY dentro del OVER. El motor irá sumando los valores conforme desciende por las filas, creando una curva de crecimiento visualmente clara en el conjunto de resultados.

Para los que analizan tendencias, el uso de LAG() es fundamental. Si necesitas comparar las ventas del primer trimestre de este año contra el del año pasado, puedes configurar un desplazamiento de 4 filas (asumiendo datos trimestrales) para traer el valor correspondiente al mismo periodo del ejercicio anterior y calcular la diferencia interanual al instante.

Diferencias clave y optimización

Es común confundir estas funciones con el GROUP BY tradicional. La diferencia es que el GROUP BY contrae las filas, transformando muchas líneas en una sola. En cambio, las funciones de ventana añaden el resultado del cálculo como una columna extra, permitiendo que cada registro conserve su identidad y sus datos originales.

Desde el punto de vista del rendimiento, hay que tener cuidado. Estas operaciones pueden ser costosas en tablas gigantescas. Una buena práctica es indexar las columnas utilizadas en PARTITION BY y ORDER BY para que el motor no tenga que reordenar los datos en memoria cada vez que ejecutes la consulta. Además, es muy recomendable combinar estas funciones con CTEs (Common Table Expressions) para mantener el código legible y organizado.

Hay un par de errores clásicos que debes evitar. El primero es intentar usar una función de ventana dentro de la cláusula WHERE; esto es imposible porque el filtrado de filas ocurre antes de que las ventanas se calculen. Si necesitas filtrar por un rango o ranking, debes envolver la consulta en una subconsulta o un CTE y aplicar el filtro en la capa exterior.

Dominar estas herramientas transforma por completo la manera en que interactuamos con los datos, permitiéndonos pasar de simples reportes de sumas a análisis multidimensionales y temporales con un esfuerzo mínimo de código. Al integrar la capacidad de no colapsar registros con el poder de las funciones de ranking y desplazamiento, cualquier analista puede extraer insights mucho más profundos y precisos de sus bases de datos.