Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Calcolo del totale parziale con la clausola OVER e la clausola PARTITION BY in SQL Server

Spesso ti imbatti in scenari in cui devi calcolare un totale parziale di una quantità.

Un totale parziale si riferisce alla somma dei valori in tutte le celle di una colonna che precede la cella successiva in quella particolare colonna.

Diamo un'occhiata a un esempio per renderlo più chiaro.

Come puoi vedere, la terza riga della colonna RunningAgeTotal contiene la somma di tutti i valori da 1 a 3 righe della colonna StudentAge, ovvero 14 + 12 + 13 =39.

Allo stesso modo, il valore della riga 4 della colonna RunningAgeTotal è 49, che è la somma dei valori da 1 a 4 righe della colonna StudentAge.

In SQL Server, la clausola OVER può essere utilizzata per calcolare i totali parziali.

Esploriamo come usarlo con l'aiuto di un esempio qui sotto.

Semplice esempio di calcolo del totale parziale SQL

Creiamo alcuni dati fittizi prima di scrivere effettivamente una query che calcola un totale parziale.

Innanzitutto, esegui il seguente script:

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 )

Questo script crea la tabella Studenti all'interno del database School. Nella tabella sono presenti quattro colonne:Id, StudentName, StudentGender e Student. L'istruzione INSERT aggiunge 10 record fittizi al database.

Per calcolare il totale parziale di sql, dobbiamo utilizzare una clausola OVER e aggiungere la colonna per la quale vogliamo calcolare il totale parziale. Lo script seguente calcola il totale parziale dei valori nella colonna StudentAge e aggiunge il risultato alla colonna RunningAgeTotal.

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

Nello script precedente, l'istruzione SELECT recupera le colonne StudentName, StudentGender e StudentAge insieme alla colonna del totale parziale, ovvero RunningAgeTotal. La funzione SUM Aggregate aggiunge i valori alla colonna StudentAge e la clausola OVER determina che l'aggiunta deve essere eseguita sotto forma di totale parziale ordinato dalla colonna Id. L'output dello script precedente è il seguente:

Calcola la media corrente SQL

È possibile modificare lo script nell'ultima sezione per calcolare un'età media corrente di tutti gli studenti nella tabella Studenti. Per fare ciò, esegui il seguente script:

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

Come puoi vedere, utilizziamo la funzione di aggregazione AVG per calcolare l'età media di tutti gli studenti nella colonna StudentAge. L'output dello script precedente è simile al seguente:

Dai un'occhiata alla terza riga della colonna RunningAgeAverage. Contiene la media dei valori delle righe da 1 a 3 nella colonna StudentAge, ovvero (14 + 12 + 13)/3 =13.

Partizionamento del totale parziale in base ai valori delle colonne

Puoi anche calcolare un totale parziale partizionando i dati in base ai valori in una determinata colonna. Ad esempio, puoi calcolare un totale parziale di sql dell'età degli studenti, partizionato per genere. Per fare ciò, devi utilizzare un'istruzione PARTITION BY insieme alla clausola OVER.

Dai un'occhiata al seguente esempio:

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

L'unica differenza tra il calcolo del totale parziale per tutti i record e il calcolo del totale parziale per genere è l'uso della clausola PARTITION BY StudentGender tra parentesi dopo la clausola OVER. Lo script precedente calcola il totale parziale per i valori nella colonna StudentAge, partizionato per i valori nella colonna StudentGender. L'output è simile a questo.

Ora, dai un'occhiata ai primi quattro valori nella colonna RunningAgeTotal (evidenziata dal rettangolo rosso). Questi valori sono il totale parziale delle studentesse. Allo stesso modo, le ultime 6 righe (evidenziate dal rettangolo verde) contengono un totale parziale dell'età degli studenti maschi nella tabella Studenti.

Problemi con OVER quando una colonna ha una colonna duplicata

Si verifica un problema se una colonna con valori duplicati viene utilizzata con una clausola OVER per calcolare un totale parziale. Dai un'occhiata alla colonna StudentAge. Elice, Edward e Josh hanno tutti la stessa età, cioè 12. Allo stesso modo, anche Liana e Liza hanno gli stessi valori nella colonna StudentAge, cioè 10.

Se provi a calcolare un totale parziale specificando la colonna StudentAge tra parentesi dopo la clausola OVER, vedrai alcuni risultati strani. Eseguiamo questa query:

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

L'output della query precedente è il seguente:

Nella seconda riga della colonna RunningAgeTotal, il valore è 29. Tuttavia, dovrebbe essere 19 perché le righe 1 e 2 della colonna StudentAge contengono rispettivamente 9 e 10. In questo caso, poiché entrambe le righe 2 e 3 della colonna StudentAge contengono un valore duplicato, ovvero 10, il valore per la riga 2 della colonna RunningAgeTotal viene calcolato sommando 9, 10 e 10. Allo stesso modo, per la riga 3 di nella colonna RunningAgeTotal, viene utilizzato il valore della seconda riga che è 29.

Allo stesso modo, se guardi la riga 5 della colonna RunningAgeTotal, il valore è 76. In realtà dovrebbe essere 40 + 12 =52. Tuttavia, poiché le righe 5, 6 e 7 della colonna StudentAge hanno valori duplicati, ovvero 12, il totale parziale viene calcolato sommando 40 + 12 + 12 + 12 =76. Questo totale parziale è stato utilizzato per le righe 6 e 7 della colonna RunningAgeTotal perché le righe 6 e 7 della colonna StudentAge contengono i valori duplicati della riga 5.

Per evitare questa situazione, è necessario interrompere l'utilizzo di colonne con valori duplicati insieme alla clausola OVER. La colonna Chiave primaria è sempre una buona scelta da utilizzare con la clausola OVER poiché contiene solo valori univoci.

Leggi anche:

Raggruppamento dei dati utilizzando le funzioni OVER e PARTITION BY

Lezioni sull'utilizzo di OVER e PARTITION BY