¿En qué orden se ejecuta una consulta SQL con funciones de ventana?
Ubica las ventanas y QUALIFY en el orden en que corre una consulta, y descubre cómo un WHERE cambia tus porcentajes.
Curso gratis. Tu Maestro, una IA, .
Si llegaste aquí desde SQL para gente de datos, ya conoces el orden en que corre una consulta: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT. Las ventanas encajan en ese orden, y saber dónde explica casi todas las sorpresas de este curso.
Las funciones de ventana se calculan después de WHERE, GROUP BY y HAVING: sobre las filas que quedaron. QUALIFY filtra justo después de las ventanas, y luego vienen ORDER BY y LIMIT.
FROM
las tablas
WHERE
quita filas
GROUP BY
junta filas en grupos
HAVING
quita grupos
SELECT y ventanas
las ventanas ven solo lo que quedó
QUALIFY
filtra con resultados de ventanas
ORDER BY
ordena el resultado
LIMIT
corta el resultado entero
Tres consecuencias que ya viviste:
WHEREno puede usar una ventana, porque cuando correWHEREla ventana no existe (página del último pedido).QUALIFYsí puede, porque corre después.- El
ORDER BYde adentro deOVERes parte del cálculo de la ventana; el que ordena lo que ves es el del final.
Y una cuarta que todavía no: lo que WHERE quita, la ventana no lo ve.
Inténtalo
El código inicial del ejercicio quiere mostrar el segundo semestre de Centro, con el porcentaje que cada mes representa del año completo. Al correrlo, julio sale como 15.4% del año, casi el doble de lo que debería. Antes de arreglarlo, contesta la pregunta de abajo: ¿por qué? Luego arréglalo sin perder el filtro de meses. Si no ves por qué cambia el porcentaje, pregúntale a tu Maestro.
Comprueba lo que sabes: El código inicial dice que julio es 15.4% del año de Centro, y en realidad es 8.0%. ¿Por qué sale casi el doble?
Tu turno
Muestra los meses de julio a diciembre de Centro con mes, ventas y pct_del_año, el porcentaje de las ventas del año completo de Centro, con un decimal. Calcula el porcentaje antes de quitar meses (con WITH o con QUALIFY). Ordena por mes. Terminaste cuando julio dice 8.0 y diciembre 9.8.
Tablas: ventas_mensuales (sucursal, mes, ventas)
ventas_mensuales · 35 filas
| Columna | Tipo |
|---|---|
| sucursal Nombre de la sucursal: Centro, Norte o Sur. | VARCHAR |
| mes Primer día del mes que resume la fila. | DATE |
| ventas Ventas del mes, en pesos. | BIGINT |
Primeras filas
| sucursal | mes | ventas |
|---|---|---|
| Centro | 2025-01-01 | 165100 |
| Centro | 2025-02-01 | 155700 |
| Centro | 2025-03-01 | 178700 |
Tab agrega sangría; Esc y Tab para salir
El WHERE mes >= '2025-07-01' quitó los primeros seis meses antes de que SUM(ventas) OVER () sumara. El denominador fue el total del semestre, no del año. Con WITH, la ventana corre sobre los 12 meses y el filtro de meses llega después. Con QUALIFY pasa lo mismo, porque QUALIFY corre después de las ventanas. En el sandbox, esta versión dio julio 8.0 y diciembre 9.8, igual que la solución:
SELECT mes, ventas, ROUND(100.0 * ventas / SUM(ventas) OVER (), 1) AS pct_del_añoFROM ventas_mensualesInicio de las líneas 4–5. WHERE sucursal = 'Centro' -- esto sí lo debe ver la ventanaQUALIFY mes >= DATE '2025-07-01' -- esto solo lo quieres ver tú Fin de las líneas 4–5.ORDER BY mes;La pregunta que conviene hacerte siempre: ¿qué filas quiero que vea la ventana, y qué filas quiero ver yo? Lo primero se filtra con WHERE; lo segundo, después.
Ventanas encima de un GROUP BY
El diagrama tiene otra consecuencia útil: las ventanas corren después de GROUP BY, así que pueden trabajar sobre los grupos ya formados. Una sola consulta puede sumar por sucursal y, además, rankear esas sumas o sacar qué parte del total es cada una. El ejemplo de abajo lo arma paso a paso.
Ranking de sucursales por su total del año
Ejemplo resuelto · 4 pasos
Queremos una fila por sucursal con su total de 2025, su lugar entre las tres y qué porcentaje de la cadena representa, en una sola consulta.
Piensa el siguiente paso por tu cuenta y luego ábrelo para comparar.
Un LIMIT no es un top por grupo. LIMIT es lo último que corre, y corta el resultado entero. En el sandbox, rankear los meses de cada sucursal y terminar con ORDER BY lugar, sucursal LIMIT 3 regresó tres filas: diciembre de Centro, diciembre de Norte y diciembre de Sur. Si querías los 3 mejores meses de cada sucursal, el corte va en QUALIFY lugar <= 3, que filtra dentro de cada partición. Esa diferencia es el reto de la página que sigue.
En entrevistas sale directo o escondido: "¿en qué orden se ejecuta esta consulta?", o una consulta con un WHERE y una ventana cuyo resultado tienes que predecir antes de correrla. También "rankea a los vendedores por sus ventas totales" esperando ver si haces un GROUP BY y luego una subconsulta, o la ventana directo sobre el agregado. Si quieres que tu Maestro te dé una consulta para predecir su resultado, pídeselo.
Cuando un porcentaje "del total" no te cuadre, busca el WHERE. Casi siempre la ventana está viendo menos filas de las que crees.
Comprueba lo que sabes, 1 de 2: En SELECT sucursal, SUM(ventas) AS total, RANK() OVER (ORDER BY SUM(ventas) DESC) AS lugar FROM ventas_mensuales GROUP BY sucursal, ¿cuántas filas ve la ventana?
Comprueba lo que sabes, 2 de 2: Una consulta numera filas con ROW_NUMBER() OVER (ORDER BY ventas DESC) y no tiene ORDER BY al final. ¿En qué orden salen las filas?