sql >> Databáze >  >> RDS >> Sqlserver

Výpočet průběžného součtu pomocí klauzule OVER a klauzule PARTITION BY na serveru SQL Server

Často se setkáváte se scénáři, kdy musíte vypočítat průběžný součet množství.

Průběžný součet odkazuje na součet hodnot ve všech buňkách sloupce, který předchází další buňce v tomto konkrétním sloupci.

Pojďme se podívat na příklad, aby to bylo jasnější.

Jak vidíte, třetí řádek sloupce RunningAgeTotal obsahuje součet všech hodnot v 1 až 3 řádcích sloupce StudentAge, tj. 14 + 12 + 13 =39.

Podobně je hodnota 4. řádku sloupce RunningAgeTotal 49, což je součet hodnot v 1 až 4 řádcích sloupce StudentAge.

V SQL Server lze klauzuli OVER použít k výpočtu průběžných součtů.

Podívejme se, jak to použít, pomocí níže uvedeného příkladu.

Jednoduchý příklad výpočtu SQL průběžného součtu

Než skutečně napíšeme dotaz, který vypočítá průběžný součet, vytvoříme nějaká fiktivní data.

Nejprve spusťte následující 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 )

Tento skript vytvoří tabulku Studenti ve školní databázi. V tabulce jsou čtyři sloupce:Id, StudentName, StudentGender a Student. Příkaz INSERT přidá do databáze 10 fiktivních záznamů.

Pro výpočet sql průběžného součtu musíme použít klauzuli OVER a přidat sloupec, pro který chceme průběžný součet vypočítat. Následující skript vypočítá průběžný součet hodnot ve sloupci StudentAge a přidá výsledek do sloupce RunningAgeTotal.

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

Ve výše uvedeném skriptu příkaz SELECT načte sloupce StudentName, StudentGender a StudentAge spolu se sloupcem průběžného součtu, tj. RunningAgeTotal. Funkce SUM Aggregate přidá hodnoty do sloupce StudentAge a klauzule OVER určuje, že sčítání by mělo být provedeno ve formě průběžného součtu seřazeného podle sloupce Id. Výstup výše uvedeného skriptu je následující:

Vypočítat průběžný průměr SQL

Skript v poslední části můžete upravit tak, aby vypočítal průběžný průměrný věk všech studentů v tabulce Studenti. Chcete-li to provést, spusťte následující 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

Jak vidíte, k výpočtu průměrného věku všech studentů ve sloupci StudentAge používáme agregační funkci AVG. Výstup výše uvedeného skriptu vypadá takto:

Podívejte se na třetí řádek sloupce RunningAgeAverage. Obsahuje průměr hodnot 1 až 3 řádků ve sloupci StudentAge, tj. (14 + 12 + 13)/3 =13.

Rozdělení průběžného součtu podle hodnot sloupců

Průběžný součet můžete také vypočítat rozdělením dat podle hodnot v konkrétním sloupci. Můžete například vypočítat sql průběžný součet věku studentů, rozdělený podle pohlaví. Chcete-li to provést, musíte použít příkaz PARTITION BY spolu s klauzulí OVER.

Podívejte se na následující příklad:

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

Jediný rozdíl mezi výpočtem průběžného součtu pro všechny záznamy a výpočtem průběžného součtu podle pohlaví je použití klauzule PARTITION BY StudentGender v závorce za klauzulí OVER. Výše uvedený skript vypočítá průběžný součet hodnot ve sloupci StudentAge, rozdělený podle hodnot ve sloupci StudentGender. Výstup vypadá takto.

Nyní se podívejte na první čtyři hodnoty ve sloupci RunningAgeTotal (zvýrazněno červeným obdélníkem). Tyto hodnoty jsou průběžným součtem studentek. Podobně posledních 6 řádků (zvýrazněných zeleným obdélníkem) obsahuje průběžný součet věku studentů mužského pohlaví v tabulce Studenti.

Problémy s OVER, když sloupec obsahuje duplicitní sloupec

Problém nastává, pokud je sloupec s duplicitními hodnotami použit s klauzulí OVER za účelem výpočtu průběžného součtu. Podívejte se do kolonky StudentAge. Elice, Edward a Josh mají všichni stejný věk, tj. 12. Podobně i Liana a Liza mají ve sloupci StudentAge stejné hodnoty, tj. 10.

Pokud se pokusíte vypočítat průběžný součet zadáním sloupce StudentAge v závorce za klauzulí OVER, uvidíte nějaké podivné výsledky. Spusťte tento dotaz:

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

Výstup výše uvedeného dotazu je následující:

Ve druhém řádku sloupce RunningAgeTotal je hodnota 29. Měla by však být 19, protože 1 a 2 řádky sloupce StudentAge obsahují 9 a 10. V tomto případě, protože 2 i 3 řádky sloupce StudentAge obsahují duplicitní hodnotu, tj. 10, se hodnota pro 2 řádek sloupce RunningAgeTotal vypočítá sečtením 9, 10 a 10. Podobně pro 3 řádek ve sloupci RunningAgeTotal se použije hodnota z druhého řádku, která je 29.

Podobně, když se podíváte na 5 řádek sloupce RunningAgeTotal, hodnota je 76. Ve skutečnosti by to mělo být 40 + 12 =52. Protože však řádky 5, 6 a 7 sloupce StudentAge mají duplicitní hodnoty, tj. 12, průběžný součet se vypočítá sečtením 40 + 12 + 12 + 12 =76. Tento průběžný součet byl použit pro řádky 6 a 7 sloupce RunningAgeTotal, protože řádky 6 a 7 sloupce StudentAge obsahují duplicitní hodnoty jako řádek 5.

Chcete-li se této situaci vyhnout, musíte přestat používat sloupce s duplicitními hodnotami spolu s klauzulí OVER. Sloupec Primární klíč je vždy dobrou volbou pro použití s ​​klauzulí OVER, protože obsahuje pouze jedinečné hodnoty.

Přečtěte si také:

Seskupování dat pomocí funkcí OVER a PARTITION BY

Lekce o používání OVER a PARTITION BY


  1. Přetrvávající UUID v PostgreSQL pomocí JPA

  2. Je do MySQL vloženo nesprávné celé číslo (2147483647)?

  3. PIVOT dotaz na odlišné záznamy

  4. Jak mohu vložit data binárního souboru do binárního pole SQL pomocí jednoduchého příkazu insert?