¿Qué diferencia hay entre PARTITION BY y GROUP BY?
Compara PARTITION BY con GROUP BY y calcula qué porcentaje del año de su sucursal es cada mes.
Curso gratis. Tu Maestro, una IA, .
GROUP BY sucursal y PARTITION BY sucursal hacen la misma primera cosa: reparten las filas en grupos según la sucursal. La diferencia está en lo que regresan.
GROUP BYresume: una fila por grupo. La Término del glosario del resultado cambia: antes había una fila por sucursal y mes; después, una por sucursal.PARTITION BYacompaña: cada fila se queda, y gana un valor calculado sobre su grupo. La granularidad no cambia.
A ese grupo se le llama partición. Una fila nunca está en dos particiones a la vez, y cada partición se calcula por su lado, como si fuera una tabla aparte. En el diagrama, sigue una fila de Norte de principio a fin.
35 filas de ventas_mensuales
una por sucursal y mes
Se reparten por sucursal
Centro 12, Norte 12, Sur 11
SUM(ventas) sobre su partición
cada fila mira solo a las de su sucursal
35 filas con total_sucursal
ninguna fila desaparece
Ahora mira las 35 filas dibujadas. Cada punto es un mes de una sucursal, en su lugar de siempre. La línea horizontal de cada color es AVG(ventas) OVER (PARTITION BY sucursal): el promedio de su partición, repetido en cada fila de esa sucursal. Ningún punto desapareció para que existiera la línea.
Si alguna vez usaste Vega-Lite o Altair, esa línea sale de joinaggregate, que es justo esto: un agregado por grupo pegado a cada fila. En SQL se escribe con OVER.
Con el valor del grupo en la misma fila, puedes comparar cada fila contra su grupo sin salir de la consulta. ventas - AVG(ventas) OVER (PARTITION BY sucursal) dice cuánto se alejó cada mes del promedio de su sucursal. En una corrida en el sandbox de Maestro, diciembre de Centro quedó 31,825 pesos arriba de su promedio redondeado (181,175).
Como cada fila conserva su detalle y tiene el total de su grupo, puedes hacer cuentas entre los dos en la misma fila. Por ejemplo, qué porcentaje del año de su sucursal es cada mes:
ROUND(100.0 * ventas / SUM(ventas) OVER (PARTITION BY sucursal), 1)El 100.0 (con punto) hace que la división dé decimales. ROUND(..., 1) deja un decimal.
Inténtalo
Escribe la consulta que regresa sucursal, mes, ventas y pct_del_año para las 35 filas. Antes de correrla, contesta la pregunta de abajo: comprometerte con un número primero hace que el resultado te diga algo. Si tus porcentajes no te cuadran, cuéntale a tu Maestro qué esperabas.
Comprueba lo que sabes: Antes de correr: a Sur le falta junio, así que tiene 11 filas. ¿Cuánto van a sumar los 11 porcentajes de Sur en pct_del_año?
Regresa sucursal, mes, ventas y pctdelaño: qué porcentaje de las ventas del año de su sucursal es cada mes, redondeado a un decimal con ROUND(..., 1). Ordena por sucursal, mes. Terminaste cuando ves 35 filas y diciembre de Centro dice 9.8.
Tu turno
Regresa sucursal, mes, ventas y pct_del_año: qué porcentaje de las ventas del año de su sucursal es cada mes, redondeado a un decimal con ROUND(..., 1). Ordena por sucursal, mes. Terminaste cuando ves 35 filas y diciembre de Centro dice 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 |
Cada ejecución empieza con copias nuevas de las tablas del curso, así que puedes probar lo que quieras. Tab agrega sangría; para salir del editor, presiona Escape y luego Tab.
Listo para ejecutar tu consulta.
Los porcentajes de cada sucursal suman 100 (o casi, por el redondeo), porque cada uno se calculó sobre su propia partición. Si hubieras usado OVER (), cada mes sería un porcentaje de las tres sucursales juntas.
Una regla para quedarte: si quieres menos filas, es GROUP BY; si quieres las mismas filas con más información, es una ventana.
Lo que conviene saber antes de usarlo en el trabajo
Puedes partir por más de una columna. PARTITION BY sucursal, date_trunc('quarter', mes) hace una partición por sucursal y trimestre. Así, cada mes se compara con su trimestre en lugar de con su año.
ROUND(100.0 * ventas / SUM(ventas) OVER (
PARTITION BY sucursal, date_trunc('quarter', mes)
), 1) AS pct_del_trimestreEn el sandbox, diciembre de Centro dio 36.0% de su cuarto trimestre, contra 9.8% de su año.
Los NULL no cuentan, pero la fila se queda. SUM, AVG y COUNT(columna) ignoran los NULL también dentro de una ventana, igual que con GROUP BY. La fila con el NULL sigue en el resultado y recibe el total de su partición; su propio porcentaje sale NULL, porque NULL entre cualquier número da NULL. Así salió en el sandbox con cuatro filas, una de ellas sin valor:
| k | x | SUM(x) OVER () | COUNT(x) OVER () | COUNT(*) OVER () |
|---|---|---|---|---|
| a | 3 | 7 | 3 | 4 |
| b | NULL | 7 | 3 | 4 |
| c | 1 | 7 | 3 | 4 |
| d | 3 | 7 | 3 | 4 |
Fíjate en las dos últimas columnas: COUNT(x) cuenta los valores y COUNT(*) cuenta las filas. Si calculas un promedio "a mano" como SUM / COUNT(*), la fila vacía te baja el promedio. Si no tienes claro cuál de los dos COUNT te sirve en tu caso, pregúntale a tu Maestro.
En entrevistas aparece como "Muestra cada venta con el promedio de su sucursal y la diferencia contra ese promedio", o "¿qué porcentaje de su categoría representa cada producto?". En los dos casos, la pista es que piden cada fila y además un dato de su grupo. Esa combinación es una ventana con PARTITION BY.
Una prueba rápida con tus datos: toma una tabla tuya con una columna de grupo y calcula el porcentaje de cada fila dentro de su grupo, como en el ejercicio. Luego suma esos porcentajes con un GROUP BY por esa misma columna. Si algún grupo no da 100 (o casi, por el redondeo), tu PARTITION BY no es el grupo que creías.