En SQL, le SUM()
La fonction est une fonction d'agrégation qui renvoie la somme de toutes les valeurs d'une expression donnée.
Il peut également être utilisé pour renvoyer la somme de toutes les valeurs distinctes (uniques) dans une expression.
L'expression doit être numérique (il ne peut pas s'agir d'une chaîne de caractères, d'une chaîne de bits ou d'une date/heure).
Vous trouverez ci-dessous quelques exemples de base pour montrer comment cela fonctionne.
Exemple de tableau
Supposons que nous ayons le tableau suivant :
SELECT * FROM Products;
Résultat :
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | ProductId | VendorId | ProductName | ProductPrice | ProductDescription | |-------------+------------+---------------------------------+----------------+-----------------------------------------| | 1 | 1001 | Left handed screwdriver | 25.99 | Purple. Includes left handed carry box. | | 2 | 1001 | Long Weight (blue) | 14.75 | Includes a long wait. | | 3 | 1001 | Long Weight (green) | 11.99 | Approximate 30 minute waiting period. | | 4 | 1002 | Sledge Hammer | 33.49 | Wooden handle. Free wine glasses. | | 5 | 1003 | Chainsaw | 245.00 | Orange. Includes spare fingers. | | 6 | 1003 | Straw Dog Box | NULL | Tied with vines. Very chewable. | | 7 | 1004 | Bottomless Coffee Mugs (4 Pack) | 9.99 | Brown ceramic with solid handle. | | 8 | 1001 | Right handed screwdriver | 25.99 | Blue. Includes right handed carry box. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Exemple
Nous pouvons utiliser la requête suivante pour obtenir la somme de tous les prix.
SELECT SUM(ProductPrice)
FROM Products;
Résultat :
+--------------------+ | (No column name) | |--------------------| | 367.20 | +--------------------+
Dans ce cas, les informations de prix sont stockées dans le ProductPrice
colonne, et nous la passons donc comme argument à la SUM()
fonction, qui calcule ensuite la somme et renvoie le résultat.
Utiliser des alias de colonne
Vous remarquerez que les résultats précédents n'incluent pas de nom de colonne. Il faut s'y attendre, car le SUM()
La fonction ne renvoie aucune colonne. Vous pouvez facilement fournir un nom de colonne en attribuant un alias.
SELECT SUM(ProductPrice) AS Sum
FROM Products;
Résultat :
+--------+ | Sum | |--------| | 367.20 | +--------+
Résultats filtrés
La SUM()
La fonction opère sur les lignes renvoyées par la requête. Donc si vous filtrez les résultats, le résultat de SUM()
reflétera cela.
SELECT SUM(ProductPrice) AS Sum
FROM Products
WHERE VendorId = 1001;
Résultat :
+-------+ | Sum | |-------| | 78.72 | +-------+
Dans ce cas, 78,72 est la somme de tous les produits proposés par le fournisseur spécifié.
NULL
Valeurs
La SUM()
la fonction ignore tout NULL
valeurs. Dans notre exemple de tableau ci-dessus, numéro de produit 6
a NULL
dans son ProductPrice
colonne, mais cela a été ignoré dans notre SUM()
exemple.
En fonction de votre SGBD et de vos paramètres, vous pouvez ou non voir un avertissement indiquant que NULL
les valeurs ont été éliminées dans le jeu de résultats.
Voici un exemple de ce que vous pourriez voir :
SELECT SUM(ProductPrice) AS Sum
FROM Products;
Résultat :
+--------+ | Sum | |--------| | 367.20 | +--------+ Warning: Null value is eliminated by an aggregate or other SET operation.
Tout cela nous indique que la colonne contenait au moins un NULL
valeur, et qu'elle a été ignorée lors du calcul des résultats.
Données de date/heure
La SUM()
la fonction n'accepte pas les expressions de date/heure.
Supposons que nous ayons le tableau suivant :
SELECT PetName, DOB
FROM Pets;
Résultat :
+-----------+------------+ | PetName | DOB | |-----------+------------| | Fluffy | 2020-11-20 | | Fetch | 2019-08-16 | | Scratch | 2018-10-01 | | Wag | 2020-03-15 | | Tweet | 2020-11-28 | | Fluffy | 2020-09-17 | | Bark | NULL | | Meow | NULL | +-----------+------------+
Si nous essayons d'utiliser SUM()
le DOB
colonne, nous aurons une erreur.
SELECT SUM(DOB) AS Sum
FROM Pets;
Résultat :
Msg 8117, Level 16, State 1, Line 1 Operand data type date is invalid for sum operator.
Données de personnage
La SUM()
la fonction n'accepte pas non plus les expressions de chaînes de caractères.
Voici ce qui se passe si nous essayons d'utiliser SUM()
sur le ProductName
colonne de nos Products
table (qui utilise un type de données de varchar):
SELECT SUM(ProductName) AS Sum
FROM Products;
Résultat :
Msg 8117, Level 16, State 1, Line 1 Operand data type varchar is invalid for sum operator.
Le DISTINCT
Mot clé
Vous pouvez utiliser le DISTINCT
mot clé avec SUM()
pour ne calculer que des valeurs distinctes. Autrement dit, s'il existe des valeurs en double, elles sont traitées comme une seule valeur.
Exemple :
SELECT SUM(DISTINCT ProductPrice) AS DistinctSum
FROM Products;
Résultat :
+---------------+ | DistinctSum | |---------------| | 341.21 | +---------------+
Nous pouvons voir que ce résultat est inférieur au résultat obtenu sans le DISTINCT
mot-clé.
Pour récapituler, nous avons obtenu 367,20 sans le DISTINCT
mot-clé, et 341.21 avec le DISTINCT
mot-clé.
En effet, deux articles partagent le même prix (le tournevis pour gaucher et le tournevis pour droitier sont tous deux au prix de 25,99). Par conséquent, la SUM()
fonction, lorsqu'elle est utilisée avec la fonction DISTINCT
mot-clé, traite ces deux valeurs comme une seule et calcule son résultat en conséquence.
Fonctions de la fenêtre
Selon votre SGBD, vous pourrez peut-être utiliser un OVER
clause avec votre SUM()
fonction pour créer une fonction de fenêtre.
Une fonction de fenêtre effectue une opération de type agrégat sur un ensemble de lignes de requête. Il produit un résultat pour chaque ligne de requête. Cela contraste avec une opération d'agrégation, qui regroupe les lignes de requête en une seule ligne de résultat.
Voici un exemple pour illustrer le concept.
Nous avons déjà vu les Products
table. Notre base de données possède également un Customers
table, et elle contient les données suivantes :
+--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+ | CustomerId | CustomerName | PostalAddress | City | StateProvince | ZipCode | Country | Phone | |--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+ | 1001 | Palm Pantry | 20 Esplanade | Townsville | QLD | 2040 | AUS | (308) 555-0100 | | 1002 | Tall Poppy | 12 Main Road | Columbus | OH | 43333 | USA | (310) 657-0134 | | 1003 | Crazy Critters | 10 Infinite Loops | Cairns | QLD | 4870 | AUS | (418) 555-0143 | | 1004 | Oops Media | 4 Beachside Drive | Perth | WA | 1234 | AUS | (405) 443-5987 | | 1005 | Strange Names Inc. | 789 George Street | Sydney | NSW | 2000 | AUD | (318) 777-0177 | | 1006 | Hi-Five Solutionists | 5 High Street | Highlands | HI | 1254 | AUS | (415) 413-5182 | +--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+
Nous pouvons récupérer des données à partir de ces tables et les présenter sous la forme d'un ensemble de résultats à l'aide d'une jointure.
Nous pouvons également utiliser le SUM()
fonction avec le OVER
clause pour appliquer une fonction de fenêtre aux données.
SELECT
v.VendorName,
p.ProductName,
p.ProductPrice,
SUM(ProductPrice) OVER (PARTITION BY v.VendorName) AS "Sum For This Vendor"
FROM Products p
INNER JOIN Vendors v
ON v.VendorId = p.VendorId
ORDER BY VendorName, ProductPrice, "Sum For This Vendor";
Résultat :
+---------------+---------------------------------+----------------+-----------------------+ | VendorName | ProductName | ProductPrice | Sum For This Vendor | |---------------+---------------------------------+----------------+-----------------------| | Katty Kittens | Bottomless Coffee Mugs (4 Pack) | 9.99 | 9.99 | | Mars Supplies | Long Weight (green) | 11.99 | 78.72 | | Mars Supplies | Long Weight (blue) | 14.75 | 78.72 | | Mars Supplies | Right handed screwdriver | 25.99 | 78.72 | | Mars Supplies | Left handed screwdriver | 25.99 | 78.72 | | Pedal Medals | Straw Dog Box | NULL | 245.00 | | Pedal Medals | Chainsaw | 245.00 | 245.00 | | Randy Roofers | Sledge Hammer | 33.49 | 33.49 | +---------------+---------------------------------+----------------+-----------------------+
Dans ce cas, nous avons utilisé le OVER
clause avec notre SUM()
fonction pour partitionner le résultat par nom de fournisseur.
Ce faisant, nous avons pu renvoyer des informations sur les prix de chaque produit, ainsi que la somme de tous les produits de ce fournisseur donné. La somme change à mesure que le fournisseur change (sauf si plusieurs fournisseurs ont la même somme), mais reste la même pour tous les produits du même fournisseur.
Ce concept peut également être appliqué à d'autres fonctions d'agrégation en SQL, telles que AVG()
, MIN()
, MAX()
, et COUNT()
.