Denna artikel kommer att omfatta SQL PARTITION BY-satsen och, i synnerhet skillnaden med GROUP BY i ett utvalt uttalande. Vi kommer också att utforska olika användningsfall av SQL PARTITION BY.
Vi använder SQL PARTITION BY för att dela resultatuppsättningen i partitioner och utföra beräkning på varje delmängd av partitionerad data.
Förbereda prov Data
Låt oss skapa en ordertabell i min exempeldatabas SQLShackDemo och infoga poster för att skriva ytterligare frågor.
Jag använder ApexSQL Generate för att infoga exempeldata i den här artikeln. Högerklicka på tabellen Order och generera testdata.
Det startar ApexSQL Generate. Jag genererade ett skript för att infoga data i ordertabellen. Kör det här skriptet för att infoga 100 poster i ordertabellen.
När vi kör infogningsuttalanden kan vi se data i tabellen Order i följande bild.
Vi använder SQL GROUP BY-satsen för att gruppera resultat efter angiven kolumn och använder aggregerade funktioner som Avg (), Min (), Max () för att beräkna önskade värden.
Gruppera efter funktionssyntax
1
2
3
4
|
VÄLJ uttryck, aggregerad funktion ()
FRÅN tabeller
VAR villkor
GROUP BY-uttryck
|
Antag att vi vill hitta följande värden i tabellen Order
- Minsta ordervärde i en stad
- Maximalt ordervärde i en stad
- Genomsnittligt ordervärde i en stad
Utför följande fråga med GROUP BY-satsen för att beräkna dessa värden.
1
2
3
4
5
6
|
VÄLJ kundanpassning,
AVG (Ordermount) AS AvgOrderAmount,
MIN (OrderAmount) AS MinOrderAmount,
SUM ( Orderamount) TotalOrderAmount
FRÅN.
GROUP BY Customercity;
|
I följande skärmdump kan vi se genomsnitt, minimum och maximala värden grupperade efter CustomerCity.
Nu vill vi även lägga till kolumnen CustomerName och OrderAmount i utdata. Låt oss lägga till dessa kolumner i select-uttalandet och köra följande kod.
1
2
3
4
5
6
|
VÄLJ Customercity, CustomerName, OrderAmount,
AVG (Orderamount) AS AvgOrderAmount,
MIN (OrderAmount) AS MinOrderAmount,
SUM (Orderamount) TotalOrderAmount
FRÅN.
GROUP BY Customercity;
|
När vi utför denna fråga får vi ett felmeddelande . I SQL GROUP BY-satsen kan vi använda en kolumn i select-satsen om den också används i Group by-sats. Det tillåter inte någon kolumn i select-satsen som inte ingår i GROUP BY-satsen.
Vi kan använda SQL DELNING AV-klausul för att lösa problemet. Låt oss utforska det vidare i nästa avsnitt.
SQL PARTITION BY
Vi kan använda SQL PARTITION BY-satsen med OVER-satsen för att specificera den kolumn som vi behöver för att aggregera . I det föregående exemplet använde vi Group By med CustomerCity-kolumnen och beräknade genomsnittliga, lägsta och högsta värden.
Låt oss köra om detta scenario med SQL PARTITION BY-satsen med hjälp av följande fråga.
id = ”abfb20057f”>
1
2
3
4
5
|
VÄLJ kundanpassning,
AVG (Orderamount) OVER (PARTITION BY Customercity) AS AvgOrderAmount,
MIN (OrderAmount) OVER (PARTITION BY Customercity) AS MinOrderAmount,
SUM (Orderamount) OVER (PARTITION BY Customercity) TotalOrderAmount
FROM.;
|
I utgången får vi aggregerade värden som liknar en GROUP Enligt klausul. Du kanske märker en skillnad i utdata för SQL PARTITION BY- och GROUP BY-satsutdata.
Gruppera efter |
SQL PARTITION BY |
Vi får ett begränsat antal poster med Group By-satsen |
Vi får alla poster i en tabell med avsnittet PARTITION BY. |
Det ger en rad per grupp i resultatuppsättning. Till exempel får vi ett resultat för varje grupp av CustomerCity i GROUP BY-satsen. |
Det ger aggregerade kolumner med varje post i den angivna tabellen. Vi har 15 poster i tabellen Order. I frågeutgången från SQL PARTITION BY får vi också 15 rader tillsammans med Min, Max och medelvärden. |
I föregående exempel får vi ett felmeddelande om vi försöker lägga till en kolumn som inte är en del av GROUP BY-satsen.
Vi kan lägga till nödvändiga kolumner i en select-sats med SQL PARTITION BY-satsen . Låt oss lägga till kundnamn och OrderAmount-kolumner och utföra följande fråga.
1
2
3
4
5
6
7
|
VÄLJ Kundanpassning,
Kundnamn,
OrderAmount,
AVG (Orderamount) OVER (PARTITION BY Customercity) AS AvgOrderAmount ,
MIN (OrderAmount) OVER (PARTITION BY Customercity) AS MinOrderAmount,
SUM (Orderamount) OVER (PARTITION BY Customercity) TotalOrderAmount
FROM.;
|
Vi får CustomerName och OrderAmount-kolumnen tillsammans med utdata från den aggregerade funktionen. Vi får också alla rader tillgängliga i beställningstabellen.
I följande skärmdump kan du för CustomerCity Chicago utföra aggregeringar (genomsnitt, min och max) och ger värden i respektive kolumner.
På samma sätt kan vi använda andra aggregerade funktioner som som räkning för att ta reda på totalt antal order i en viss stad med SQL PARTITION BY-klausulen.
1
2
3
4
5
6
7
8
|
VÄLJ kundanpassning,
Kundnamn,
OrderAmount,
COUNT (OrderID) OVER (PARTITION BY Customercity) AS CountOfOrders,
AVG (Orderamount) OVER (PARTITION BY Customercity) AS AvgOrderAmount,
MIN (OrderAmount) OVER (PARTITIO N BY Customercity) SOM MinOrderAmount,
SUM (Orderamount) OVER (PARTITION BY Customercity) TotalOrderAmount
FROM.;
|
Vi kan se orderantal för en viss stad. Till exempel har vi därför två beställningar från Austin city; det visar värde 2 i kolumnen CountofOrders.
PARTITION BY-sats med ROW_NUMBER ()
Vi kan använd SQL PARTITION BY-satsen med ROW_NUMBER () -funktionen för att ha ett radnummer för varje rad. Vi definierar följande parametrar för att använda ROW_NUMBER med SQL PARTITION BY-satsen.
- PARTITION BY-kolumn – I det här exemplet vill vi dela data i CustomerCity-kolumnen
- Beställ efter : I kolumnen ORDER BY definierar vi en kolumn eller ett tillstånd som definierar radnummer. I det här exemplet vill vi sortera data i kolumnen OrderAmount
1
2
3
4
5
6
7
8
9
10
|
VÄLJ Kundanpassning,
Kundnamn,
ROW_NUMBER () OVER (PARTITION BY Customercity
ORDER BY OrderAmount DESC) AS ”Row Number”,
OrderAmount,
COUNT (OrderID) OVER (PARTITION BY Customercity) AS CountOfOrders,
AVG (Orderamount) OVER (PARTITION BY Customercity) AS AvgOrderAmount,
MIN (OrderAmount) OVER (PARTITION BY Customercity) AS MinOrderAmount,
SUM (Orderamount) OVER (PARTITION BY Customercity) TotalOrderAmount
FROM.;
|
I följande skärmdump får vi se för CustomerCity Chicago , vi har rad nummer 1 för order med högsta belopp 7577.90. det ger radnummer med fallande OrderAmount.
PARTITION BY-sats med kumulativt totalvärde
Anta att vi vill få en kumulativ summa för beställningarna i en partition.Kumulativt totalt bör vara av den aktuella raden och följande rad i partitionen.
Till exempel i Chicago city, vi har fyra beställningar.
CustomerCity |
CustomerName |
Rank |
OrderAmount |
Kumulativa totala rader |
Kumulativt totalt |
Chicago |
Marvin |
Rank 1 +2 |
|||
Chicago |
Lawrence |
Rank 2 + 3 |
|||
Chicago |
Alex |
Rank 3 + 4 |
|||
Chicago |
Jerome |
Rank 4 |
I följande fråga har vi angett ROWS-satsen att se föreläsa den aktuella raden (med CURRENT ROW) och nästa rad (med 1 FÖLJANDE). Den beräknar vidare summan på dessa rader med summan (Orderamount) med en partition på CustomerCity (med OVER (PARTITION BY Customercity ORDER BY OrderAmount DESC).
1
2
3
4
5
6
7
|
VÄLJ kundanpassning,
Kundnamn,
OrderAmount,
ROW_NUMBER () OVER (PARTITION BY Customercity
ORDER BY OrderAmount DESC) AS ”Row Number”,
CONVERT (VARCHAR (20), SUM (orderamount) OVER (PARTITION BY Customercity
BESTÄLLA PÅ OrderAmount DESC ROWS MELLAN AKTUELL RAD OCH 1 FÖLJANDE), 1) SOM CumulativeTotal,
|
På samma sätt kan vi beräkna det kumulativa genomsnittet med följande fråga med SQL PARTITION BY-satsen.
1
2
3
4
5
6
7
|
VÄLJ Kundanpassning,
Kundnamn,
OrderAmount,
ROW_NUMBER () ÖVER (DELNING PER kundanpassning
BESTÄLLNING efter OrderAmount DESC) SOM ”Radnummer”,
CONVERT (VARCHAR (20), AVG (ordermount) OVER (PARTITION BY Customercity
BESTÄLLNING efter OrderAmount DESC ROWS MELLAN AKTUELL RAD OCH 1 FÖLJANDE)) , 1) SOM KumulativAVG
|
RADER OGRÄNSAD FÖRFÖRANDE med PARTITION BY-klausulen
Vi kan använda ROWS UNBOUNDED PRECEDING med SQL PARTITION BY-klausulen för att välja en rad i en partition före den aktuella raden och det högsta värdet r ow efter aktuell rad.
I följande tabell kan vi se för rad 1; den har ingen rad med ett högt värde i denna partition. Därför är det kumulativa genomsnittsvärdet detsamma som för rad 1 OrderAmount.
För rad2 letar det efter nuvarande radvärde (7199.61) och högsta värde rad 1 (7577.9). Det beräknar genomsnittet för dessa två belopp.
För rad 3 letar det efter nuvarande värde (6847,66) och högre belopp än det här värdet som är 7199,61 och 7577,90. Det beräknar genomsnittet av dessa och returnerar.
CustomerCity |
Kundnamn |
Rank |
OrderAmount |
Kumulativa genomsnittliga rader |
Kumulativt medelvärde |
Chicago |
Marvin |
Rank 1 |
|||
Chicago |
Lawrence |
Rank 1 + 2 |
|||
Chicago |
Alex |
Rank 1 + 2 + 3 |
|||
Chicago |
Jerome |
Rank 1 + 2 + 3 + 4 |
Utför följande fråga för att få detta resultat med våra exempeldata.
1
2
3
4
5
6
7
8
|
VÄLJ Kundanpassning,
Kundnamn,
OrderAmount,
ROW_NUMBER () ÖVER (DELNING AV Kundanpassning
BESTÄLLNING AV OrderAmount DESC) SOM ”Radnummer”,
CONVERT (VARCHAR (20), AVG (orderamount) OVER (PARTITION BY Customercity
ORDER BY OrderAmount DESC ROWS OBEGRÄNSAD föregående), 1) SOM CumulativeAvg
FRÅN.;
|
Slutsats
I den här artikeln undersökte vi SQL PARTIION BY-satsen och dess jämförelse med GROUP BY-satsen. Vi lärde oss dess användning med några exempel. Jag hoppas att du tycker att den här artikeln är användbar och gärna ställer frågor i kommentarerna nedan
- Författare
- Senaste inlägg
Han är skaparen av en av de största gratis onlinesamlingarna av artiklar om ett enda ämne, med sin 50-delarserie om SQL Server Always On Availability Groups. Baserat på sitt bidrag till SQL Server-communityn har han fått utmärkelser med olika utmärkelser, inklusive den prestigefyllda ”Årets bästa författare” kontinuerligt 2020 och 2021 på SQLShack.
Raj är alltid intresserad av nya utmaningar så om du behöver rådgivning hjälp om alla ämnen som omfattas av hans skrifter, han kan nås på [email protected]
Visa alla inlägg av Rajendra Gupta
- Sessionstidsavbrott i SQL Server Alltid tillgängligt Grupper – 8 februari 2021
- Utför uppgraderingar av mindre och större versioner för AWS RDS SQL Server – 29 januari 2021
- Distribuera AWS RDS PostgreSQL-instanser – 27 januari 2021