I SQL er SUM()
funktion er en aggregeret funktion, der returnerer summen af alle værdier i et givet udtryk.
Det kan også bruges til at returnere summen af alle distinkte (unikke) værdier i et udtryk.
Udtrykket skal være numerisk (det kan ikke være tegnstreng, bitstreng eller datetime).
Nedenfor er nogle grundlæggende eksempler for at demonstrere, hvordan det virker.
Eksempeltabel
Antag, at vi har følgende tabel:
SELECT * FROM Products;
Resultat:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | 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. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Eksempel
Vi kan bruge følgende forespørgsel til at få summen af alle priser.
SELECT SUM(ProductPrice)
FROM Products;
Resultat:
+--------------------+ | (No column name) | |--------------------| | 367.20 | +--------------------+
I dette tilfælde gemmes prisoplysninger i ProductPrice
kolonne, og så sender vi det som et argument til SUM()
funktion, som så beregner summen og returnerer resultatet.
Brug af kolonnealiaser
Du vil bemærke, at de tidligere resultater ikke indeholder et kolonnenavn. Dette kan forventes, fordi SUM()
funktion returnerer ikke nogen kolonner. Du kan nemt angive et kolonnenavn ved at tildele et alias.
SELECT SUM(ProductPrice) AS Sum
FROM Products;
Resultat:
+--------+ | Sum | |--------| | 367.20 | +--------+
Filtrerede resultater
SUM()
funktionen fungerer på de rækker, der returneres af forespørgslen. Så hvis du filtrerer resultaterne, er resultatet af SUM()
vil afspejle det.
SELECT SUM(ProductPrice) AS Sum
FROM Products
WHERE VendorId = 1001;
Resultat:
+-------+ | Sum | |-------| | 78.72 | +-------+
I dette tilfælde er 78,72 summen af alle de produkter, der tilbydes af den angivne leverandør.
NULL
Værdier
SUM()
funktionen ignorerer enhver NULL
værdier. I vores eksempeltabel ovenfor, produktnummer 6
har fået NULL
i dens ProductPrice
kolonne, men det blev ignoreret i vores SUM()
eksempel.
Afhængigt af dit DBMS og dine indstillinger kan du muligvis se en advarsel, der NULL
værdier blev elimineret i resultatsættet.
Her er et eksempel på, hvad du kan se:
SELECT SUM(ProductPrice) AS Sum
FROM Products;
Resultat:
+--------+ | Sum | |--------| | 367.20 | +--------+ Warning: Null value is eliminated by an aggregate or other SET operation.
Alt dette fortæller os er, at kolonnen indeholdt mindst én NULL
værdi, og at den blev ignoreret ved beregning af resultaterne.
Data-/tidsdata
SUM()
Funktionen accepterer ikke dato/tidsudtryk.
Antag, at vi har følgende tabel:
SELECT PetName, DOB
FROM Pets;
Resultat:
+-----------+------------+ | 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 | +-----------+------------+
Hvis vi prøver at bruge SUM()
på DOB
kolonne, får vi en fejl.
SELECT SUM(DOB) AS Sum
FROM Pets;
Resultat:
Msg 8117, Level 16, State 1, Line 1 Operand data type date is invalid for sum operator.
Tegndata
SUM()
funktion accepterer heller ikke tegnstrengsudtryk.
Her er, hvad der sker, hvis vi forsøger at bruge SUM()
på ProductName
kolonne i vores Products
tabel (som bruger en datatype varchar):
SELECT SUM(ProductName) AS Sum
FROM Products;
Resultat:
Msg 8117, Level 16, State 1, Line 1 Operand data type varchar is invalid for sum operator.
DISTINCT
Søgeord
Du kan bruge DISTINCT
søgeord med SUM()
kun at beregne distinkte værdier. Det vil sige, at hvis der er nogen duplikerede værdier, behandles de som én værdi.
Eksempel:
SELECT SUM(DISTINCT ProductPrice) AS DistinctSum
FROM Products;
Resultat:
+---------------+ | DistinctSum | |---------------| | 341.21 | +---------------+
Vi kan se, at dette resultat er lavere end det resultat, vi fik uden DISTINCT
søgeord.
For at opsummere fik vi 367,20 uden DISTINCT
nøgleord og 341.21 med DISTINCT
søgeord.
Dette skyldes, at der er to varer, der deler samme pris (venstrehåndsskruetrækker og højrehåndsskruetrækker er begge prissat til 25,99). Derfor er SUM()
funktion, når den bruges sammen med DISTINCT
søgeord, behandler begge disse værdier som én og beregner resultatet i overensstemmelse hermed.
Vinduefunktioner
Afhængigt af dit DBMS, kan du muligvis bruge en OVER
klausul med din SUM()
funktion for at oprette en vinduesfunktion.
En vinduesfunktion udfører en aggregatlignende operation på et sæt forespørgselsrækker. Det producerer et resultat for hver forespørgselsrække. Dette er i modsætning til en aggregeret operation, som grupperer forespørgselsrækker i en enkelt resultatrække.
Her er et eksempel for at demonstrere konceptet.
Vi har allerede set Products
bord. Vores database har også en Customers
tabel, og den indeholder følgende data:
+--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+ | 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 | +--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+
Vi kan hente data fra disse tabeller og præsentere dem som ét resultatsæt ved at bruge en join.
Vi kan også bruge SUM()
funktion med OVER
klausul for at anvende en vinduesfunktion til dataene.
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";
Resultat:
+---------------+---------------------------------+----------------+-----------------------+ | 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 | +---------------+---------------------------------+----------------+-----------------------+
I dette tilfælde brugte vi OVER
klausul med vores SUM()
funktion til at opdele resultatet efter leverandørnavn.
Ved at gøre dette var vi i stand til at returnere prisoplysninger for hvert produkt, samt summen af alle produkter fra den pågældende leverandør. Summen ændres, efterhånden som leverandøren ændres (medmindre flere leverandører tilfældigvis har den samme sum), men forbliver den samme for alle produkter fra samme leverandør.
Dette koncept kan også anvendes på andre aggregerede funktioner i SQL, såsom AVG()
, MIN()
, MAX()
og COUNT()
.