sql >> Base de Datos >  >> RDS >> Sqlserver

Cuándo y cómo usar la cláusula SQL PARTITION BY

En este artículo, exploraremos cuándo y cómo usar la cláusula SQL PARTITION BY y la compararemos con el uso de la cláusula GROUP BY.

Comprender la función Ventana

Los usuarios de bases de datos utilizan funciones agregadas como MAX(), MIN(), AVERAGE() y COUNT() para realizar análisis de datos. Estas funciones operan en una tabla completa y devuelven datos agregados únicos mediante la cláusula GROUP BY. A veces, requerimos valores agregados en un pequeño conjunto de filas. En este caso, la función Ventana combinada con la función agregada ayuda a lograr el resultado deseado. La función Ventana usa la cláusula OVER() y puede incluir las siguientes funciones:

  • Dividir por:  Esto divide las filas o el conjunto de resultados de la consulta en pequeñas particiones.
  • Ordenar por:  Esto organiza las filas en orden ascendente o descendente para la ventana de partición. El orden predeterminado es ascendente.
  • Fila o rango:  Puede limitar aún más las filas en una partición especificando los puntos inicial y final.

En este artículo, nos centraremos en explorar la cláusula SQL PARTITION BY.

Preparación de datos de muestra

Supongamos que tenemos una tabla [VentasLT].[Pedidos] que almacena los detalles de los pedidos de los clientes. Tiene una columna [Ciudad] que especifica la ciudad del cliente donde se realizó el pedido.

CREATE TABLE [SalesLT].[Orders]
(
orderid INT,
orderdate DATE,
customerName VARCHAR(100),
City VARCHAR(50),
amount MONEY
)
INSERT INTO [SalesLT].[Orders]
SELECT 1,'01/01/2021','Mohan Gupta','Alwar',10000
UNION ALL
SELECT 2,'02/04/2021','Lucky Ali','Kota',20000
UNION ALL
SELECT 3,'03/02/2021','Raj Kumar','Jaipur',5000
UNION ALL
SELECT 4,'04/02/2021','Jyoti Kumari','Jaipur',15000
UNION ALL
SELECT 5,'05/03/2021','Rahul Gupta','Jaipur',7000
UNION ALL
SELECT 6,'06/04/2021','Mohan Kumar','Alwar',25000
UNION ALL
SELECT 7,'07/02/2021','Kashish Agarwal','Alwar',15000
UNION ALL
SELECT 8,'08/03/2021','Nagar Singh','Kota',2000
UNION ALL
SELECT 9,'09/04/2021','Anil KG','Alwar',1000
Go

Digamos que queremos saber el valor total de los pedidos por ubicación (Ciudad). Para este propósito, usamos la función SUM() y GROUP BY como se muestra a continuación.

SELECT City AS CustomerCity
,sum(amount) AS totalamount FROM [SalesLT].[Orders]
GROUP BY city
ORDER BY city

En el conjunto de resultados, no podemos usar las columnas no agregadas en la instrucción SELECT. Por ejemplo, no podemos mostrar [CustomerName] en la salida porque no está incluido en la cláusula GROUP BY.

SQL Server muestra el siguiente mensaje de error si intenta utilizar la columna no agregada en la lista de columnas.

SELECT City AS CustomerCity, CustomerName,amount,
SUM(amount) OVER(PARTITION BY city) TotalOrderAmount
FROM [SalesLT].[Orders]

Como se muestra a continuación, la cláusula PARTITION BY crea una ventana más pequeña (conjunto de filas de datos), realiza la agregación y la muestra. También puede ver columnas no agregadas en esta salida.

De manera similar, puede usar las funciones AVG(), MIN(), MAX() para calcular la cantidad promedio, mínima y máxima de las filas en una ventana.

SELECT City AS CustomerCity, CustomerName,amount,
SUM(amount) OVER(PARTITION BY city) TotalOrderAmount,
Avg(amount) OVER(PARTITION BY city) AvgOrderAmount,
Min(amount) OVER(PARTITION BY city) MinOrderAmount,
MAX(amount) OVER(PARTITION BY city) MaxOrderAmount
FROM [SalesLT].[Orders]

Uso de la cláusula SQL PARTITION BY con la función ROW_NUMBER()

Previamente, obtuvimos los valores agregados en una ventana usando la cláusula PARTITION BY. Supongamos que en lugar del total, requerimos el total acumulativo en una partición.

Un total acumulativo funciona de las siguientes maneras.

Fila Total acumulado
1 Rango 1+ 2
2 Rango 2+3
3 Rango 3+4

El rango de la fila se calcula usando la función ROW_NUMBER(). Primero usemos esta función y veamos las clasificaciones de las filas.

  • La función ROW_NUMBER() usa la cláusula OVER y PARTITION BY y clasifica los resultados en orden ascendente o descendente. Comienza a clasificar filas desde 1 por orden de clasificación.
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number]
FROM [SalesLT].[Orders]

Por ejemplo, en la ciudad [Alwar], la fila con la cantidad más alta (25000.00) está en la fila 1. Como se muestra a continuación, clasifica las filas en la ventana especificada por la cláusula PARTITION BY. Por ejemplo, tenemos tres ciudades diferentes [Alwar], [Jaipur] y [Kota], y cada ventana (ciudad) obtiene sus rangos de fila.

Para calcular el total acumulado, usamos los siguientes argumentos.

  • FILA ACTUAL:Especifica el punto inicial y final en el rango especificado.
  • 1 siguiente:Especifica el número de filas (1) a seguir desde la fila actual.
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number],
SUM(amount) OVER(PARTITION BY city ORDER BY amount DESC ROWS BETWEEN
CURRENT ROW AND 1 FOLLOWING) AS CumulativeSUM
FROM [SalesLT].[Orders]

La siguiente imagen muestra que obtiene un total acumulativo en lugar de un total general en una ventana especificada por la cláusula PARTITION BY.

Si usamos ROWS UNBOUNDED PRECEDING  en la cláusula SQL PARTITION BY, calcula el total acumulado de la siguiente manera. Utiliza las filas actuales junto con las filas que tienen los valores más altos en la ventana especificada.

Fila Total acumulado
1 Rango 1
2 Rango 1+2
3 Rango 1+2+3
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number],
SUM(amount) OVER(PARTITION BY city ORDER BY amount DESC
ROWS UNBOUNDED PRECEDING) AS CumulativeSUM
FROM [SalesLT].[Orders]

Comparación de la cláusula GROUP BY y SQL PARTITION BY

AGRUPAR POR PARTICIÓN POR
Devuelve una fila por grupo después de calcular los valores agregados. Devuelve todas las filas de la declaración SELECT junto con columnas adicionales de valores agregados.
No podemos usar la columna no agregada en la instrucción SELECT. Podemos usar las columnas requeridas en la declaración SELECT y no produce ningún error para la columna no agregada.
Requiere usar la cláusula HAVING para filtrar registros de la declaración SELECT. La función PARTITION puede tener predicados adicionales en la cláusula WHERE además de las columnas utilizadas en la declaración SELECT.
El GROUP BY se usa en agregados regulares. PARTITION BY se usa en agregados en ventana.
No podemos usarlo para calcular números de fila o sus rangos. Puede calcular números de fila y sus rangos en la ventana más pequeña.

Poniéndolo en uso

Se recomienda utilizar la cláusula SQL PARTITION BY al trabajar con varios grupos de datos para los valores agregados en el grupo individual. De manera similar, se puede usar para ver las filas originales con la columna adicional de valores agregados.