I SQL er AVG()
funktion er en aggregeret funktion, der returnerer gennemsnittet af alle værdier i et givet udtryk.
Det kan også bruges til at returnere gennemsnittet 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:
+-------------+-------------+------------------------ --------------+----------------+------------------------ ----------------------------+| Produkt-id | VendorId | Produktnavn | Produktpris | Produktbeskrivelse ||--------------+---------------------- --------------+----------------+------------------------ ----------------------|| 1 | 1001 | Venstrehåndet skruetrækker | 25,99 | Lilla. Inkluderer venstrehåndskasse. || 2 | 1001 | Lang vægt (blå) | 14.75 | Inkluderer lang ventetid. || 3 | 1001 | Lang vægt (grøn) | 11,99 | Cirka 30 minutters ventetid. || 4 | 1002 | Slædehammer | 33,49 | Træhåndtag. Gratis vinglas. || 5 | 1003 | Motorsav | 245,00 | Orange. Inkluderer ekstra fingre. || 6 | 1003 | Halmhundekasse | NULL | Bundet med vinstokke. Meget tyggeligt. || 7 | 1004 | Bundløse kaffekrus (4 pakke) | 9,99 | Brun keramik med solidt håndtag. || 8 | 1001 | Højrehåndsskruetrækker | 25,99 | Blå. Inkluderer højrehåndskasse. |+-------------+-------------+---------------------- ------------+----------------+-------------------- ----------------------+
Eksempel
Vi kan bruge følgende forespørgsel til at få gennemsnittet af alle priser.
SELECT AVG(ProductPrice)
FROM Products;
Resultat:
+----------------------------+| (Intet kolonnenavn) ||------------------------|| 52.457142 |+--------------------+
I dette tilfælde gemmes prisoplysninger i ProductPrice
kolonne, og så sender vi det som et argument til AVG()
funktion, som så beregner gennemsnittet og returnerer resultatet.
Brug af kolonnealiaser
Du vil bemærke, at de tidligere resultater ikke indeholder et kolonnenavn. Dette kan forventes, fordi AVG()
funktion returnerer ikke nogen kolonner. Du kan nemt angive et kolonnenavn ved at tildele et alias.
SELECT AVG(ProductPrice) AS Average
FROM Products;
Resultat:
+------------+| Gennemsnit ||------------|| 52.457142 |+------------+
Filtrerede resultater
AVG()
funktionen fungerer på de rækker, der returneres af forespørgslen. Så hvis du filtrerer resultaterne, vil resultatet af AVG()
vil afspejle det.
SELECT AVG(ProductPrice) AS Average
FROM Products
WHERE VendorId = 1001;
Resultat:
+------------+| Gennemsnit ||------------|| 19,680000 |+------------+
I dette tilfælde er 19,680000 gennemsnitsprisen for alle de produkter, der tilbydes af den angivne leverandør.
NULL
Værdier
AVG()
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 AVG()
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 AVG(ProductPrice) AS Average
FROM Products;
Resultat:
+------------+| Gennemsnit ||------------|| 52.457142 |+------------+Advarsel:Nulværdi er elimineret af en samlet eller anden SET-handling.
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
AVG()
Funktionen accepterer ikke dato/tidsudtryk.
Antag, at vi har følgende tabel:
SELECT PetName, DOB
FROM Pets;
Resultat:
+-------+-------------+| Kæledyrsnavn | DOB ||------------------------|| Fluffy | 20-11-2020 || Hent | 2019-08-16 || Ridse | 2018-10-01 || Wag | 15-03-2020 || Tweet | 28-11-2020 || Fluffy | 2020-09-17 || Bark | NULL || Mjav | NULL |+-----------+------------+
Hvis vi prøver at bruge AVG()
på DOB
kolonne, får vi en fejl.
SELECT AVG(DOB) AS Average
FROM Pets;
Resultat:
Besked 8117, niveau 16, tilstand 1, linje 1Operand datatypedato er ugyldig for gennemsnitsoperatør.
Tegndata
AVG()
funktion accepterer heller ikke tegnstrengsudtryk.
Her er, hvad der sker, hvis vi forsøger at bruge AVG()
på ProductName
kolonne i vores Products
tabel (som bruger en datatype varchar):
SELECT AVG(ProductName) AS Average
FROM Products;
Resultat:
Besked 8117, niveau 16, tilstand 1, linje 1Operand datatypen varchar er ugyldig for gennemsnitsoperatør.
DISTINCT
Søgeord
Du kan bruge DISTINCT
søgeord med AVG()
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 AVG(DISTINCT ProductPrice) AS DistinctAverage
FROM Products;
Resultat:
+------------------------+| DistinctAverage ||------------------------|| 56.868333 |+------------------------+
Vi kan se, at dette resultat er højere end det resultat, vi fik uden DISTINCT
søgeord.
For at opsummere fik vi 52.457142 uden DISTINCT
søgeord og 56.868333 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 AVG()
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 AVG()
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:
+--------------+-----------------------------+-------- -------------------------------------- -----+-----------+----------------+| Kunde-id | Kundenavn | Postadresse | By | StateProvince | Postnummer | Land | Telefon ||-----------------------------------+-------- ----------+------------+-----------------+-------- ----+-----------+----------------+| 1001 | Palm Pantry | Esplanade 20 | Townsville | QLD | 2040 | AUS | (308) 555-0100 || 1002 | Høj valmue | Hovedvej 12 | Columbus | ÅH | 43333 | USA | (310) 657-0134 || 1003 | Skøre væsner | 10 uendelige sløjfer | Cairns | QLD | 4870 | AUS | (418) 555-0143 || 1004 | Ups Medier | 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 | Højlandet | HEJ | 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 AVG()
funktion med OVER
klausul for at anvende en vinduesfunktion til dataene.
SELECT
v.VendorName,
p.ProductName,
p.ProductPrice,
AVG(ProductPrice) OVER (PARTITION BY v.VendorName) AS "Average For This Vendor"
FROM Products p
INNER JOIN Vendors v
ON v.VendorId = p.VendorId
ORDER BY VendorName, ProductPrice, "Average For This Vendor";
Resultat:
+----------------+------------------------------------- ---+----------------+-----------------------------------+| Leverandørnavn | Produktnavn | ProduktPris | Gennemsnit for denne leverandør ||---------------+-------------------------------- -----+----------------+---------------------------- || Katty killinger | Bundløse kaffekrus (4 pakke) | 9,99 | 9,990000 || Mars forsyninger | Lang vægt (grøn) | 11,99 | 19.680000 || Mars forsyninger | Lang vægt (blå) | 14,75 | 19.680000 || Mars forsyninger | Højrehåndsskruetrækker | 25,99 | 19.680000 || Mars forsyninger | Venstrehåndet skruetrækker | 25,99 | 19.680000 || Pedalmedaljer | Straw Dog Box | NULL | 245.000000 || Pedalmedaljer | Motorsav | 245,00 | 245.000000 || Randy Roofers | Slædehammer | 33,49 | 33.490000 |+--------+---------------------------------------- --+----------------+-----------------------------------+I dette tilfælde brugte vi
OVER
klausul med voresAVG()
funktion til at opdele resultatet efter leverandørnavn.Ved at gøre dette var vi i stand til at returnere prisoplysninger for hvert produkt, såvel som gennemsnitsprisen for alle produkter fra den pågældende leverandør. Den gennemsnitlige pris ændres, efterhånden som leverandøren ændrer sig (medmindre flere leverandører tilfældigvis har det samme gennemsnit), men forbliver den samme for alle produkter fra den samme leverandør.
Dette koncept kan også anvendes på andre aggregerede funktioner i SQL, såsom
SUM()
,MIN()
,MAX()
ogCOUNT()
.