sql >> Databasteknik >  >> RDS >> Sqlserver

Beräkna löpande total med OVER-klausul och PARTITION BY-klausul i SQL Server

Du stöter ofta på scenarier där du måste beräkna en löpande summa av en kvantitet.

En löpande summa hänvisar till summan av värden i alla celler i en kolumn som föregår nästa cell i den specifika kolumnen.

Låt oss ta en titt på ett exempel för att göra detta tydligare.

Som du kan se innehåller den tredje raden i kolumnen RunningAgeTotal summan av alla värden i 1 till 3 raderna i kolumnen StudentAge, dvs 14 + 12 + 13 =39.

På samma sätt är värdet på 4-raderna i kolumnen RunningAgeTotal 49, vilket är summan av värdena i 1 till 4-raderna i kolumnen StudentAge.

I SQL Server kan OVER-satsen användas för att beräkna löpande summor.

Låt oss utforska hur du använder detta med hjälp av ett exempel nedan.

Enkelt exempel på att beräkna SQL Running Total

Låt oss skapa lite dummy-data innan vi faktiskt skriver en fråga som beräknar en löpande summa.

Kör först följande skript:

CREATE DATABASE School
GO

USE School
GO

CREATE TABLE Students
(
	Id INT PRIMARY KEY IDENTITY,
	StudentName VARCHAR (50),
	StudentGender VARCHAR (50),
	StudentAge INT
)
GO

INSERT INTO Students VALUES ('Sally', 'Female', 14 )
INSERT INTO Students VALUES ('Edward', 'Male', 12 )
INSERT INTO Students VALUES ('Jon', 'Male', 13 )
INSERT INTO Students VALUES ('Liana', 'Female', 10 )
INSERT INTO Students VALUES ('Ben', 'Male', 11 )
INSERT INTO Students VALUES ('Elice', 'Female', 12 )
INSERT INTO Students VALUES ('Nick', 'Male', 9 )
INSERT INTO Students VALUES ('Josh', 'Male', 12 )
INSERT INTO Students VALUES ('Liza', 'Female', 10 )
INSERT INTO Students VALUES ('Wick', 'Male', 15 )

Det här skriptet skapar tabellen Studenter i skolans databas. Det finns fyra kolumner i tabellen:Id, StudentName, StudentGender och Student. INSERT-satsen lägger till 10 dummy-poster till databasen.

För att beräkna sql-summan måste vi använda en OVER-sats och lägga till kolumnen som vi vill beräkna den löpande summan för. Följande skript beräknar den löpande summan av värdena i kolumnen StudentAge och lägger till resultatet i kolumnen RunningAgeTotal.

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY Id) AS RunningAgeTotal
FROM Students

I skriptet ovan hämtar SELECT-satsen kolumnerna StudentName, StudentGender och StudentAge tillsammans med den löpande totalkolumnen, d.v.s. RunningAgeTotal. Funktionen SUM Aggregate lägger till värdena i kolumnen StudentAge och OVER-satsen bestämmer att tillägget ska utföras i form av löpande total beställt av Id-kolumnen. Utdata från skriptet ovan är som följer:

Beräkna SQL Running Average

Du kan ändra skriptet i det sista avsnittet för att beräkna en löpande medelålder för alla elever i tabellen Studenter. För att göra detta, kör följande skript:

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY Id) AS RunningAgeTotal,
AVG (StudentAge) OVER (ORDER BY Id) AS RunningAgeAverage
FROM Students

Som du kan se använder vi AVG-aggregatfunktionen för att beräkna medelåldern för alla elever i kolumnen StudentAge. Utdata från ovanstående skript ser ut så här:

Ta en titt på den tredje raden i kolumnen RunningAgeAverage. Den innehåller medelvärdet av värden för de 1 till 3 raderna i kolumnen StudentAge, dvs (14 + 12 + 13)/3 =13.

Partitionering av löpande summa efter kolumnvärden

Du kan också beräkna en löpande summa genom att partitionera data med värdena i en viss kolumn. Du kan till exempel beräkna en sql-summa för elevernas ålder, uppdelad efter kön. För att göra detta måste du använda en PARTITION BY-sats tillsammans med OVER-satsen.

Ta en titt på följande exempel:

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (PARTITION BY StudentGender ORDER BY Id) AS RunningAgeTotal
FROM Students

Den enda skillnaden mellan att beräkna den löpande summan för alla poster och att beräkna den löpande summan efter kön är användningen av PARTITION BY StudentGender-satsen inom parentesen efter OVER-satsen. Skriptet ovan beräknar den löpande summan för värdena i kolumnen StudentAge, uppdelad av värdena i kolumnen StudentGender. Utgången ser ut så här.

Ta nu en titt på de fyra första värdena i kolumnen RunningAgeTotal (markerad av den röda rektangeln). Dessa värden är den löpande summan av de kvinnliga studenterna. På samma sätt innehåller de sista 6 raderna (markerade med den gröna rektangeln) en löpande summa av åldern för de manliga eleverna i Elevtabellen.

Problem med OVER när en kolumn har en dubblettkolumn

Ett problem uppstår om en kolumn med dubbletter av värden används med en OVER-sats för att beräkna en löpande summa. Ta en titt på kolumnen StudentAge. Elice, Edward och Josh har alla samma ålder, d.v.s. 12. På samma sätt har Liana och Liza också samma värden i kolumnen StudentAge, d.v.s. 10.

Om du försöker beräkna en löpande summa genom att ange kolumnen StudentAge inom parentesen efter OVER-satsen, kommer du att se några konstiga resultat. Låt oss köra den här frågan:

USE School
SELECT Id, StudentName, StudentGender, StudentAge,
SUM (StudentAge) OVER (ORDER BY StudentAge) AS RunningAgeTotal
FROM Students

Utdata från ovanstående fråga är som följer:

I den andra raden i kolumnen RunningAgeTotal är värdet 29. Det bör dock vara 19 eftersom 1 och 2 raderna i kolumnen StudentAge innehåller 9 respektive 10. I det här fallet, eftersom både 2 och 3 rader i kolumnen StudentAge innehåller ett duplicerat värde, d.v.s. 10, beräknas värdet för 2-raden i kolumnen RunningAgeTotal genom att lägga till 9, 10 och 10. På samma sätt, för 3-raden i kolumnen RunningAgeTotal. kolumnen RunningAgeTotal används värdet från den andra raden som är 29.

På samma sätt, om du tittar på raden 5 i kolumnen RunningAgeTotal, är värdet 76. Det borde faktiskt vara 40 + 12 =52. Men eftersom 5, 6 och 7 raderna i kolumnen StudentAge har dubbla värden, d.v.s. 12, den löpande summan beräknas genom att lägga till 40 + 12 + 12 + 12 =76. Denna löpande summa har använts för raderna 6 och 7 i kolumnen RunningAgeTotal eftersom raderna 6 och 7 i kolumnen StudentAge innehåller dubblettvärdena som raden 5.

För att undvika denna situation måste du sluta använda kolumner med dubbletter av värden tillsammans med OVER-satsen. Kolumnen Primärnyckel är alltid ett bra val att använda med OVER-satsen eftersom den bara innehåller unika värden.

Läs även:

Gruppera data med funktionerna OVER och PARTITION BY

Lektioner om att använda OVER och PARTITION BY


  1. T-SQL vs SQL

  2. Få den sista dagen i månaden i SQL

  3. Logga in på Microsoft SQL Server Fel:18456

  4. Intermittenta ODBC-anslutningsfel