PARTITION BY en SQL: qué es, cómo funciona y ejemplos prácticos

La cláusula PARTITION BY en SQL se utiliza dentro de las funciones de ventana para dividir un conjunto de resultados en grupos (particiones) sobre los cuales se aplicará un cálculo.

👉 Es similar a GROUP BY, pero con una diferencia importante: PARTITION BY no agrupa ni reduce filas, sino que conserva todas las filas y calcula el valor por partición.

Se suele usar con funciones como ROW_NUMBER(), RANK(), SUM(), AVG(), MIN(), MAX(), entre otras.

Sintaxis básica de PARTITION BY

SELECT columnas,
       funcion() OVER (PARTITION BY columna ORDER BY columna2)
FROM tabla;

Elementos clave:

  • funcion() → función de ventana (ej. ROW_NUMBER(), SUM(), etc.).
  • OVER → indica que es una función de ventana.
  • PARTITION BY → divide las filas en grupos.
  • ORDER BY (opcional) → ordena dentro de cada partición.

Si no conocés bien cómo funciona el ORDER BY dentro de OVER, revisá el artículo dedicado.

Ejemplo básico de PARTITION BY

Tabla ventas:

idcliente_idtotal
11100
21200
32150
42300
53400

Consulta:

SELECT cliente_id,
       total,
       SUM(total) OVER (PARTITION BY cliente_id) AS total_por_cliente
FROM ventas;

Resultado:

cliente_idtotaltotal_por_cliente
1100300
1200300
2150450
2300450
3400400

👉 Cada cliente conserva todas sus filas, pero aparece el total de sus compras en cada una.

Diferencia entre GROUP BY y PARTITION BY

  • GROUP BY: agrupa y devuelve una fila por grupo.
  • PARTITION BY: conserva todas las filas y agrega el valor calculado por grupo.

Ejemplo con GROUP BY:

SELECT cliente_id, SUM(total) AS total_por_cliente
FROM ventas
GROUP BY cliente_id;

Resultado:

cliente_idtotal_por_cliente
1300
2450
3400

👉 Aquí perdemos el detalle de cada compra.

Con PARTITION BY, mantenemos las filas individuales y además el total.

Ejemplo práctico: ranking de ventas por cliente

SELECT cliente_id,
       total,
       ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY total DESC) AS ranking
FROM ventas;

Resultado:

cliente_idtotalranking
12001
11002
23001
21502
34001

👉 Devuelve un ranking de compras dentro de cada cliente.

Ejemplo: promedio por departamento

SELECT nombre,
       departamento,
       salario,
       AVG(salario) OVER (PARTITION BY departamento) AS promedio_dep
FROM empleados;

👉 Cada empleado conserva su fila, pero se muestra también el salario promedio de su departamento.

Ejemplo: primer pedido por cliente

SELECT cliente_id,
       fecha,
       ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY fecha ASC) AS orden
FROM pedidos;

👉 Permite identificar cuál fue el primer pedido de cada cliente.

PARTITION BY sin ORDER BY

Si usamos solo PARTITION BY sin ORDER BY, la función se aplica al grupo completo sin importar el orden.

Ejemplo:

SELECT cliente_id,
       COUNT(*) OVER (PARTITION BY cliente_id) AS num_pedidos
FROM pedidos;

👉 Devuelve el número total de pedidos por cliente en cada fila.

Errores comunes con PARTITION BY

  1. Confundirlo con GROUP BY
    👉 GROUP BY reduce filas, PARTITION BY no.
  2. Olvidar el ORDER BY dentro de OVER cuando se necesita ranking
ROW_NUMBER() OVER (PARTITION BY cliente_id) -- ❌ No define orden
  1. Esperar que PARTITION BY funcione fuera de OVER
    👉 No es independiente, siempre va dentro de funciones de ventana.
  2. Pensar que PARTITION BY mejora rendimiento
    👉 Es una función analítica, no un índice ni optimización.

Buenas prácticas con PARTITION BY

  • Usar PARTITION BY en reportes y análisis de datos detallados.
  • Siempre acompañar con ORDER BY cuando se requiera un ranking o acumulado ordenado.
  • Evitar usarlo en tablas gigantes sin índices adecuados, puede ser costoso.
  • Documentar qué función de ventana se aplica y sobre qué columna.

Casos de uso comunes de PARTITION BY

  1. Ranking de ventas por categoría
  2. Acumulados por cliente o departamento
  3. Promedios móviles por fechas
  4. Detección de primeros y últimos registros
  5. Comparación de un valor con el promedio del grupo

PARTITION BY en distintos motores de base de datos

  • PostgreSQL: soporta completamente funciones de ventana con PARTITION BY.
  • MySQL: desde la versión 8 soporta funciones de ventana.
  • SQL Server: soporta PARTITION BY desde versiones antiguas.
  • Oracle: tiene soporte completo desde hace años.
  • SQLite: soporta desde la versión 3.25.

👉 Hoy en día, prácticamente todos los motores modernos soportan PARTITION BY.

Preguntas frecuentes (FAQ)

1. ¿Puedo usar PARTITION BY sin ORDER BY?
Sí, se aplica al grupo completo sin necesidad de orden.

2. ¿Cuál es la diferencia con GROUP BY?
GROUP BY devuelve una fila por grupo; PARTITION BY conserva todas las filas.

3. ¿Puedo usar varias columnas en PARTITION BY?
Sí, por ejemplo:

PARTITION BY departamento, puesto

4. ¿Qué pasa si no incluyo PARTITION BY?
La función se aplica a todas las filas como un único grupo.

5. ¿Afecta el rendimiento?
Sí, especialmente en tablas muy grandes. Es recomendable usar índices.

Conclusión

La cláusula PARTITION BY en SQL es una herramienta poderosa para el análisis avanzado de datos:

  • Permite dividir resultados en grupos sin perder detalle.
  • Funciona junto a funciones de ventana como ROW_NUMBER(), SUM(), AVG().
  • Es esencial en reportes, rankings, acumulados y comparaciones.

Dominar PARTITION BY marca la diferencia entre consultas básicas y análisis avanzados en SQL.

Estudia particiones por ventana en CASE y funciones de ventana y repasa términos en el Glosario SQL completo.

Scroll al inicio