Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Quando e como usar a cláusula SQL PARTITION BY




Neste artigo, vamos explorar quando e como usar a cláusula SQL PARTITION BY e compará-la ao uso da cláusula GROUP BY.

Compreendendo a função Janela


Os usuários de banco de dados usam funções agregadas como MAX(), MIN(), AVERAGE() e COUNT() para realizar a análise de dados. Essas funções operam em uma tabela inteira e retornam dados agregados únicos usando a cláusula GROUP BY. Às vezes, exigimos valores agregados em um pequeno conjunto de linhas. Nesse caso, a função Window combinada com a função agregada ajuda a obter a saída desejada. A função Window usa a cláusula OVER() e pode incluir as seguintes funções:
  • Particionar por:  Isso divide as linhas ou o conjunto de resultados da consulta em pequenas partições.
  • Ordenar por:  Isso organiza as linhas em ordem crescente ou decrescente para a janela de partição. A ordem padrão é crescente.
  • Linha ou intervalo:  Você pode limitar ainda mais as linhas em uma partição especificando o início e os pontos de extremidade.

Neste artigo, vamos nos concentrar em explorar a cláusula SQL PARTITION BY.

Preparando dados de amostra


Suponha que tenhamos uma tabela [SalesLT].[Orders] que armazena os detalhes do pedido do cliente. Possui uma coluna [Cidade] que especifica a cidade do cliente de onde o pedido foi feito.
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 o valor total dos pedidos por local (Cidade). Para isso, usamos a função SUM() e GROUP BY conforme mostrado abaixo.
SELECT City AS CustomerCity
,sum(amount) AS totalamount FROM [SalesLT].[Orders]
GROUP BY city
ORDER BY city



No conjunto de resultados, não podemos usar as colunas não agregadas na instrução SELECT. Por exemplo, não podemos exibir [CustomerName] na saída porque não está incluído na cláusula GROUP BY.

O SQL Server fornece a seguinte mensagem de erro se você tentar usar a coluna não agregada na lista de colunas.


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

Conforme mostrado abaixo, a cláusula PARTITION BY cria uma janela menor (conjunto de linhas de dados), realiza a agregação e a exibe. Você também pode visualizar colunas não agregadas nesta saída.



Da mesma forma, você pode usar as funções AVG(), MIN(), MAX() para calcular o valor médio, mínimo e máximo das linhas em uma janela.
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]


Usando a cláusula SQL PARTITION BY com a função ROW_NUMBER()


Anteriormente, obtínhamos os valores agregados em uma janela usando a cláusula PARTITION BY. Suponha que, em vez do total, exijamos o total cumulativo em uma partição.

Um total cumulativo funciona das seguintes maneiras.
Linha Total acumulado
1 Classificação 1+ 2
2 Classificação 2+3
3 Classificação 3+4

A classificação da linha é calculada usando a função ROW_NUMBER(). Vamos primeiro usar esta função e ver as fileiras das linhas.
  • A função ROW_NUMBER() usa a cláusula OVER e PARTITION BY e classifica os resultados em ordem crescente ou decrescente. Ele começa a classificar as linhas de 1 por ordem de classificação.
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number]
FROM [SalesLT].[Orders]

Por exemplo, na cidade [Alwar], a linha com o valor mais alto (25.000,00) está na linha 1. Conforme mostrado abaixo, ela classifica as linhas na janela especificada pela cláusula PARTITION BY. Por exemplo, temos três cidades diferentes [Alwar], [Jaipur] e [Kota], e cada janela (cidade) recebe suas fileiras de linhas.



Para calcular o total acumulado, usamos os seguintes argumentos.
  • CURRENT ROW:especifica o ponto inicial e final no intervalo especificado.
  • 1 seguinte:especifica o número de linhas (1) a seguir da linha atual.
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]

A imagem a seguir mostra que você obtém um total cumulativo em vez de um total geral em uma janela especificada pela cláusula PARTITION BY.



Se usarmos ROWS UNBOUNDED PRECEDING  na cláusula SQL PARTITION BY, ele calcula o total acumulado da seguinte maneira. Ele usa as linhas atuais junto com as linhas com os valores mais altos na janela especificada.
Linha Total acumulado
1 Classificação 1
2 Classificação 1+2
3 Classificação 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]


Comparando a cláusula GROUP BY e SQL PARTITION BY

GRUPAR POR PARTIÇÃO POR
Ele retorna uma linha por grupo após calcular os valores agregados. Ele retorna todas as linhas da instrução SELECT junto com colunas adicionais de valores agregados.
Não podemos usar a coluna não agregada na instrução SELECT. Podemos usar colunas obrigatórias na instrução SELECT e isso não produz erros para a coluna não agregada.
Requer o uso da cláusula HAVING para filtrar registros da instrução SELECT. A função PARTITION pode ter predicados adicionais na cláusula WHERE além das colunas usadas na instrução SELECT.
O GROUP BY é usado em agregados regulares. PARTITION BY é usado em agregados em janela.
Não podemos usá-lo para calcular números de linha ou suas classificações. Ele pode calcular números de linha e suas classificações na janela menor.

Colocando em uso


É recomendável usar a cláusula SQL PARTITION BY ao trabalhar com vários grupos de dados para os valores agregados no grupo individual. Da mesma forma, pode ser usado para visualizar as linhas originais com a coluna adicional de valores agregados.