I SQL, AVG()
funktion är en aggregerad funktion som returnerar medelvärdet av alla värden i ett givet uttryck.
Den kan också användas för att returnera medelvärdet av alla distinkta (unika) värden i ett uttryck.
Uttrycket måste vara numeriskt (det kan inte vara teckensträng, bitsträng eller datetime).
Nedan följer några grundläggande exempel för att visa hur det fungerar.
Exempeltabell
Anta att vi har följande tabell:
SELECT * FROM Products;
Resultat:
+-------------+------------+------------------------ --------------+----------------+------------------------ ----------------------------+| Produkt-ID | VendorId | Produktnamn | Produktpris | Produktbeskrivning ||-------------+---------------------- -------------+----------------+------------------------ ----------------------------|| 1 | 1001 | Vänsterhänt skruvmejsel | 25,99 | Lila. Inkluderar vänsterhänt bärlåda. || 2 | 1001 | Lång vikt (blå) | 14.75 | Inkluderar lång väntan. || 3 | 1001 | Lång vikt (grön) | 11,99 | Cirka 30 minuters väntetid. || 4 | 1002 | Slägga | 33,49 | Trähandtag. Gratis vinglas. || 5 | 1003 | Motorsåg | 245,00 | Orange. Inkluderar extra fingrar. || 6 | 1003 | Halmhundlåda | NULL | Bind med vinstockar. Mycket tuggbar. || 7 | 1004 | Bottenlösa kaffemuggar (4-pack) | 9,99 | Brun keramik med rejält handtag. || 8 | 1001 | Högerhänt skruvmejsel | 25,99 | Blå. Inkluderar högerhänt bärlåda. |+-------------+-------------+----------------------------- ------------+----------------+-------------------- ---------------------+
Exempel
Vi kan använda följande fråga för att få ett genomsnitt av alla priser.
SELECT AVG(ProductPrice)
FROM Products;
Resultat:
+----------------------------+| (Inget kolumnnamn) ||------------------------|| 52.457142 |+--------------------+
I det här fallet lagras prisinformation i ProductPrice
kolumnen, och så skickar vi det som ett argument till AVG()
funktion, som sedan beräknar medelvärdet och returnerar resultatet.
Använda kolumnalias
Du kommer att märka att de tidigare resultaten inte innehåller ett kolumnnamn. Detta är att vänta, eftersom AVG()
funktion returnerar inga kolumner. Du kan enkelt ange ett kolumnnamn genom att tilldela ett alias.
SELECT AVG(ProductPrice) AS Average
FROM Products;
Resultat:
+------------+| Genomsnitt ||----------------|| 52.457142 |+-----------+
Filtrerade resultat
AVG()
funktionen fungerar på raderna som returneras av frågan. Så om du filtrerar resultaten blir resultatet av AVG()
kommer att återspegla det.
SELECT AVG(ProductPrice) AS Average
FROM Products
WHERE VendorId = 1001;
Resultat:
+------------+| Genomsnitt ||----------------|| 19,680000 |+-----------+
I det här fallet är 19,680000 genomsnittspriset för alla produkter som erbjuds av den angivna leverantören.
NULL
Värden
AVG()
funktionen ignorerar någon NULL
värden. I vår exempeltabell ovan, produktnummer 6
har NULL
i dess ProductPrice
kolumn, men det ignorerades i vår AVG()
exempel.
Beroende på ditt DBMS och dina inställningar kanske du ser en varning som NULL
värden eliminerades i resultatuppsättningen.
Här är ett exempel på vad du kan se:
SELECT AVG(ProductPrice) AS Average
FROM Products;
Resultat:
+------------+| Genomsnitt ||----------------|| 52.457142 |+------------+Varning:Nullvärde elimineras av en aggregerad eller annan SET-operation.
Allt detta säger oss är att kolumnen innehöll minst en NULL
värde, och att det ignorerades vid beräkning av resultaten.
Datum/tiddata
AVG()
funktionen accepterar inte datum/tid uttryck.
Anta att vi har följande tabell:
SELECT PetName, DOB
FROM Pets;
Resultat:
+-------+------------+| PetName | DOB ||-------------------------|| Fluffig | 2020-11-20 || Hämta | 2019-08-16 || Skrapa | 2018-10-01 || Wag | 2020-03-15 || Tweet | 2020-11-28 || Fluffig | 2020-09-17 || Bark | NULL || Mjau | NULL |+-----------+------------+
Om vi försöker använda AVG()
på DOB
kolumnen får vi ett felmeddelande.
SELECT AVG(DOB) AS Average
FROM Pets;
Resultat:
Msg 8117, Level 16, State 1, Line 1Operand data type date är ogiltigt för avg operator.
Teckendata
AVG()
funktion accepterar inte heller teckensträngsuttryck.
Här är vad som händer om vi försöker använda AVG()
på ProductName
kolumnen i våra Products
tabell (som använder en datatyp av varchar):
SELECT AVG(ProductName) AS Average
FROM Products;
Resultat:
Msg 8117, Level 16, State 1, Line 1Operand data type varchar är ogiltig för avg operator.
DISTINCT
Nyckelord
Du kan använda DISTINCT
nyckelord med AVG()
för att endast beräkna distinkta värden. Det vill säga, om det finns några dubbletter av värden, behandlas de som ett värde.
Exempel:
SELECT AVG(DISTINCT ProductPrice) AS DistinctAverage
FROM Products;
Resultat:
+------------------------+| DistinctAverage ||------------------------|| 56.868333 |+------------------------+
Vi kan se att detta resultat är högre än resultatet vi fick utan DISTINCT
nyckelord.
För att sammanfatta fick vi 52.457142 utan DISTINCT
nyckelord och 56.868333 med DISTINCT
nyckelord.
Detta beror på att det finns två artiklar som delar samma pris (vänsterskruvmejseln och högerskruvmejseln kostar båda 25,99). Därför är AVG()
funktion, när den används med DISTINCT
nyckelord, behandlar båda dessa värden som ett och beräknar resultatet därefter.
Fönsterfunktioner
Beroende på ditt DBMS kan du kanske använda en OVER
sats med din AVG()
funktion för att skapa en fönsterfunktion.
En fönsterfunktion utför en aggregatliknande operation på en uppsättning frågerader. Det ger ett resultat för varje frågerad. Detta till skillnad från en aggregerad operation, som grupperar frågerader i en enda resultatrad.
Här är ett exempel för att demonstrera konceptet.
Vi har redan sett Products
tabell. Vår databas har också en Customers
tabell och den innehåller följande data:
+--------------+-----------------------------+-------- --------------------------------+------- -----+-----------+----------------+| Kund-ID | Kundnamn | Postadress | Stad | StateProvince | Postnummer | Land | Telefon ||--------------+----------------------------+-------- ----------+------------+------------------------+-------- ----+-----------+----------------+| 1001 | Palmskafferi | Esplanaden 20 | Townsville | QLD | 2040 | AUS | (308) 555-0100 || 1002 | Lång vallmo | Huvudväg 12 | Columbus | ÅH | 43333 | USA | (310) 657-0134 || 1003 | Crazy Critters | 10 oändliga slingor | Cairns | QLD | 4870 | AUS | (418) 555-0143 || 1004 | Hoppsan 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 | Höglandet | HEJ | 1254 | AUS | (415) 413-5182 |+---------------+----------------------+---- --------------+------------+----------------+--- ----------+-----------+----------------+
Vi kan hämta data från dessa tabeller och presentera dem som en resultatuppsättning genom att använda en join.
Vi kan också använda AVG()
funktion med OVER
sats för att tillämpa en fönsterfunktion på data.
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:
+----------------+------------------------------------- ---+----------------+-----------------------------------+| Leverantörsnamn | Produktnamn | ProduktPris | Genomsnitt för denna leverantör ||---------------+-------------------------------- -----+----------------+---------------------------- || Katty Kattungar | Bottenlösa kaffemuggar (4-pack) | 9,99 | 9,990000 || Mars Tillbehör | Lång vikt (grön) | 11,99 | 19,680000 || Mars Tillbehör | Lång vikt (blå) | 14.75 | 19,680000 || Mars Tillbehör | Högerskruvmejsel | 25,99 | 19,680000 || Mars Tillbehör | Vänsterhänt skruvmejsel | 25,99 | 19,680000 || Pedalmedaljer | Straw Dog Box | NULL | 245.000000 || Pedalmedaljer | Motorsåg | 245,00 | 245.000000 || Randy Roofers | Slägga | 33.49 | 33,490000 |+--------------+------------------------------------- --+----------------+-----------------------------------+I det här fallet använde vi
OVER
sats med vårAVG()
funktion för att partitionera resultatet efter leverantörsnamn.Genom att göra detta kunde vi returnera prisinformation för varje produkt, såväl som det genomsnittliga priset för alla produkter från den givna leverantören. Det genomsnittliga priset ändras när leverantören ändras (såvida inte flera leverantörer råkar ha samma genomsnitt), men förblir detsamma för alla produkter från samma leverantör.
Det här konceptet kan även tillämpas på andra aggregerade funktioner i SQL, såsom
SUM()
,MIN()
,MAX()
ochCOUNT()
.