Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Calcul du total cumulé avec la clause OVER et la clause PARTITION BY dans SQL Server

Vous rencontrez souvent des scénarios dans lesquels vous devez calculer le total cumulé d'une quantité.

Un total cumulé fait référence à la somme des valeurs de toutes les cellules d'une colonne qui précède la cellule suivante dans cette colonne particulière.

Prenons un exemple pour clarifier cela.

Comme vous pouvez le voir, la troisième ligne de la colonne RunningAgeTotal contient la somme de toutes les valeurs des lignes 1 à 3 de la colonne StudentAge, c'est-à-dire 14 + 12 + 13 =39.

De même, la valeur de la ligne 4 de la colonne RunningAgeTotal est 49, qui est la somme des valeurs des lignes 1 à 4 de la colonne StudentAge.

Dans SQL Server, la clause OVER peut être utilisée pour calculer les totaux cumulés.

Explorons comment l'utiliser à l'aide d'un exemple ci-dessous.

Exemple simple de calcul du total cumulé SQL

Créons des données factices avant d'écrire une requête qui calcule un total cumulé.

Tout d'abord, exécutez le script suivant :

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 )

Ce script crée la table Students dans la base de données School. Le tableau comporte quatre colonnes :Id, StudentName, StudentGender et Student. L'instruction INSERT ajoute 10 enregistrements factices à la base de données.

Pour calculer le total cumulé sql, nous devons utiliser une clause OVER et ajouter la colonne pour laquelle nous voulons calculer le total cumulé. Le script suivant calcule le total cumulé des valeurs de la colonne StudentAge et ajoute le résultat à la colonne RunningAgeTotal.

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

Dans le script ci-dessus, l'instruction SELECT récupère les colonnes StudentName, StudentGender et StudentAge ainsi que la colonne du total cumulé, c'est-à-dire RunningAgeTotal. La fonction SUM Aggregate ajoute les valeurs à la colonne StudentAge et la clause OVER détermine que l'addition doit être effectuée sous la forme d'un total cumulé classé par la colonne Id. La sortie du script ci-dessus est la suivante :

Calculer la moyenne courante SQL

Vous pouvez modifier le script de la dernière section pour calculer l'âge moyen cumulé de tous les élèves de la table Élèves. Pour cela, exécutez le script suivant :

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

Comme vous pouvez le voir, nous utilisons la fonction d'agrégat AVG pour calculer l'âge moyen de tous les étudiants dans la colonne StudentAge. La sortie du script ci-dessus ressemble à ceci :

Jetez un œil à la troisième ligne de la colonne RunningAgeAverage. Il contient la moyenne des valeurs des 1 à 3 lignes de la colonne StudentAge, c'est-à-dire (14 + 12 + 13)/3 =13.

Partitionner le total cumulé par valeurs de colonne

Vous pouvez également calculer un total cumulé en partitionnant les données selon les valeurs d'une colonne particulière. Par exemple, vous pouvez calculer un total cumulé sql de l'âge des étudiants, réparti par sexe. Pour ce faire, vous devez utiliser une instruction PARTITION BY avec la clause OVER.

Jetez un œil à l'exemple suivant :

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

La seule différence entre le calcul du total cumulé pour tous les enregistrements et le calcul du total cumulé par sexe est l'utilisation de la clause PARTITION BY StudentGender entre parenthèses après la clause OVER. Le script ci-dessus calcule le total cumulé des valeurs de la colonne StudentAge, partitionné par les valeurs de la colonne StudentGender. La sortie ressemble à ceci.

Examinez maintenant les quatre premières valeurs de la colonne RunningAgeTotal (mises en évidence par le rectangle rouge). Ces valeurs sont le total cumulé des étudiantes. De même, les 6 dernières lignes (surlignées par le rectangle vert) contiennent un total cumulé de l'âge des étudiants masculins dans le tableau des étudiants.

Problèmes avec OVER lorsqu'une colonne a une colonne en double

Un problème survient si une colonne avec des valeurs en double est utilisée avec une clause OVER afin de calculer un total cumulé. Jetez un œil à la colonne StudentAge. Elice, Edward et Josh ont tous le même âge, c'est-à-dire 12 ans. De même, Liana et Liza ont également les mêmes valeurs dans la colonne StudentAge, c'est-à-dire 10.

Si vous essayez de calculer un total cumulé en spécifiant la colonne StudentAge entre parenthèses après la clause OVER, vous verrez des résultats étranges. Exécutons cette requête :

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

Le résultat de la requête ci-dessus est le suivant :

Dans la deuxième ligne de la colonne RunningAgeTotal, la valeur est 29. Cependant, elle doit être 19 car les lignes 1 et 2 de la colonne StudentAge contiennent respectivement 9 et 10. Dans ce cas, étant donné que les lignes 2 et 3 de la colonne StudentAge contiennent une valeur dupliquée, c'est-à-dire 10, la valeur de la ligne 2 de la colonne RunningAgeTotal est calculée en ajoutant 9, 10 et 10. De même, pour la ligne 3 de la colonne RunningAgeTotal, la valeur de la deuxième ligne qui est 29 est utilisée.

De même, si vous regardez la ligne 5 de la colonne RunningAgeTotal, la valeur est 76. Elle devrait en fait être 40 + 12 =52. Cependant, comme les lignes 5, 6 et 7 de la colonne StudentAge ont des valeurs en double, c'est-à-dire 12, le total cumulé est calculé en additionnant 40 + 12 + 12 + 12 =76. Ce total cumulé a été utilisé pour les lignes 6 et 7 de la colonne RunningAgeTotal car les lignes 6 et 7 de la colonne StudentAge contiennent les valeurs en double comme ligne 5.

Pour éviter cette situation, vous devez cesser d'utiliser des colonnes avec des valeurs en double avec la clause OVER. La colonne Clé primaire est toujours un bon choix à utiliser avec la clause OVER car elle ne contient que des valeurs uniques.

Lire aussi :

Regroupement de données à l'aide des fonctions OVER et PARTITION BY

Leçons sur l'utilisation de OVER et PARTITION BY