Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Кога и как да използвате клаузата на SQL PARTITION BY

В тази статия ще проучим кога и как да използваме SQL клаузата PARTITION BY и ще я сравним с използването на клаузата GROUP BY.

Разбиране на функцията Window

Потребителите на база данни използват агрегатни функции като MAX(), MIN(), AVERAGE() и COUNT() за извършване на анализ на данни. Тези функции работят върху цяла таблица и връщат единични агрегирани данни с помощта на клаузата GROUP BY. Понякога изискваме обобщени стойности за малък набор от редове. В този случай функцията Window, комбинирана с функцията за обобщаване, помага за постигане на желания резултат. Функцията Window използва клаузата OVER() и може да включва следните функции:

  • Разделяне по:  Това разделя редовете или резултата от заявката на малки дялове.
  • Поръчайте по:  Това подрежда редовете във възходящ или низходящ ред за прозореца на дяла. Редът по подразбиране е възходящ.
  • Ред или диапазон:  Можете допълнително да ограничите редовете в дял, като посочите началната и крайната точка.

В тази статия ще се съсредоточим върху изследването на клаузата на SQL PARTITION BY.

Подготвяне на примерни данни

Да предположим, че имаме таблица [SalesLT].[Orders], която съхранява подробности за поръчката на клиента. Има колона [Град], която посочва града на клиента, където е направена поръчката.

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

Да кажем, че искаме да знаем общата стойност на поръчките по местоположение (град). За тази цел използваме функциите SUM() и GROUP BY, както е показано по-долу.

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

В резултатния набор не можем да използваме неагрегираните колони в оператора SELECT. Например, не можем да покажем [CustomerName] в изхода, защото не е включено в клаузата GROUP BY.

SQL Server дава следното съобщение за грешка, ако се опитате да използвате неагрегираната колона в списъка с колони.

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

Както е показано по-долу, клаузата PARTITION BY създава по-малък прозорец (набор от редове с данни), извършва агрегирането и го показва. Можете също да видите неагрегирани колони в този изход.

По същия начин можете да използвате функциите AVG(), MIN(), MAX(), за да изчислите средната, минималната и максималната сума от редовете в прозорец.

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]

Използване на клаузата на SQL PARTITION BY с функцията ROW_NUMBER()

Преди това получавахме обобщените стойности в прозорец, използвайки клаузата PARTITION BY. Да предположим, че вместо общата сума изискваме кумулативната сума в дял.

Кумулативната сума работи по следните начини.

Ред Общо с натрупване
1 Ранг 1+ 2
2 Ранг 2+3
3 Ранг 3+4

Рангът на реда се изчислява с помощта на функцията ROW_NUMBER(). Нека първо използваме тази функция и да видим редовете на редовете.

  • Функцията ROW_NUMBER() използва клаузата OVER и PARTITION BY и сортира резултатите във възходящ или низходящ ред. Започва да подрежда редовете от 1 според реда на сортиране.
SELECT City AS CustomerCity, CustomerName,amount,
ROW_NUMBER() OVER(PARTITION BY city ORDER BY amount DESC) AS [Row Number]
FROM [SalesLT].[Orders]

Например, в града [Alwar], редът с най-висока сума (25000,00) е в ред 1. Както е показано по-долу, той подрежда редовете в прозореца, определен от клаузата PARTITION BY. Например имаме три различни града [Алвар], [Джайпур] и [Кота] и всеки прозорец (град) получава своите редове.

За да изчислим кумулативната сума, използваме следните аргументи.

  • ТЕКУЩ РЕД:Посочва началната и крайната точка в посочения диапазон.
  • 1 следното:Посочва броя на редовете (1), които следват от текущия ред.
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]

Следното изображение показва, че получавате кумулативен сбор вместо обща сума в прозорец, определен от клаузата PARTITION BY.

Ако използваме РЕДОВЕ НЕОГРАНИЧЕНИ ПРЕДШЕСТВА  в SQL PARTITION BY клаузата изчислява кумулативната сума по следния начин. Той използва текущите редове заедно с редовете с най-високи стойности в посочения прозорец.

Ред Общо с натрупване
1 Ранг 1
2 Ранг 1+2
3 Ранг 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]

Сравняване на клаузата GROUP BY и SQL PARTITION BY

ГРУПА ПО РАЗДЕЛЯНЕ ПО
Връща един ред на група след изчисляване на обобщените стойности. Връща всички редове от оператора SELECT заедно с допълнителни колони с обобщени стойности.
Не можем да използваме неагрегираната колона в израза SELECT. Можем да използваме задължителни колони в израза SELECT и той не създава никакви грешки за неагрегираната колона.
Изисква използване на клаузата HAVING за филтриране на записи от оператора SELECT. Функцията PARTITION може да има допълнителни предикати в клаузата WHERE освен колоните, използвани в израза SELECT.
ГРУПАТА BY се използва в обикновени агрегати. PARTITION BY се използва в агрегати с прозорец.
Не можем да го използваме за изчисляване на номера на редове или техния ранг. Може да изчислява номера на редове и техните рангове в по-малкия прозорец.

Предлага се за употреба

Препоръчително е да използвате клаузата на SQL PARTITION BY, докато работите с множество групи данни за агрегираните стойности в отделната група. По същия начин може да се използва за преглед на оригинални редове с допълнителна колона с обобщени стойности.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server преобразува низ в дата и час

  2. Как мога да премахна дублиращи се редове?

  3. Ще се представят ли заявките ANSI JOIN спрямо не-ANSI JOIN по различен начин?

  4. Индекси на SQL Server:Ключови изисквания, въздействие върху производителността и съображения

  5. Изпълнете динамична заявка с go в sql