In SQL, il AVG()
function è una funzione aggregata che restituisce la media di tutti i valori in una determinata espressione.
Può anche essere utilizzato per restituire la media di tutti i valori distinti (unici) in un'espressione.
L'espressione deve essere numerica (non può essere stringa di caratteri, stringa di bit o data/ora).
Di seguito sono riportati alcuni esempi di base per dimostrare come funziona.
Tabella di esempio
Supponiamo di avere la seguente tabella:
SELECT * FROM Products;
Risultato:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | 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. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Esempio
Possiamo utilizzare la seguente query per ottenere la media di tutti i prezzi.
SELECT AVG(ProductPrice)
FROM Products;
Risultato:
+--------------------+ | (No column name) | |--------------------| | 52.457142 | +--------------------+
In questo caso, le informazioni sul prezzo sono memorizzate nel ProductPrice
colonna, e quindi lo passiamo come argomento a AVG()
funzione, che quindi calcola la media e restituisce il risultato.
Utilizzo degli alias di colonna
Noterai che i risultati precedenti non includono un nome di colonna. Questo è prevedibile, perché AVG()
la funzione non restituisce alcuna colonna. Puoi facilmente fornire un nome di colonna assegnando un alias.
SELECT AVG(ProductPrice) AS Average
FROM Products;
Risultato:
+-----------+ | Average | |-----------| | 52.457142 | +-----------+
Risultati filtrati
Il AVG()
La funzione opera sulle righe restituite dalla query. Quindi, se filtri i risultati, il risultato di AVG()
lo rifletterà.
SELECT AVG(ProductPrice) AS Average
FROM Products
WHERE VendorId = 1001;
Risultato:
+-----------+ | Average | |-----------| | 19.680000 | +-----------+
In questo caso, 19,680000 è il prezzo medio di tutti i prodotti offerti dal venditore specificato.
NULL
Valori
Il AVG()
la funzione ignora qualsiasi NULL
valori. Nella nostra tabella di esempio sopra, il numero del prodotto 6
ha NULL
nel suo ProductPrice
colonna, ma è stata ignorata nel nostro AVG()
esempio.
A seconda del tuo DBMS e delle tue impostazioni, potresti visualizzare o meno un avviso che NULL
i valori sono stati eliminati nel set di risultati.
Ecco un esempio di ciò che potresti vedere:
SELECT AVG(ProductPrice) AS Average
FROM Products;
Risultato:
+-----------+ | Average | |-----------| | 52.457142 | +-----------+ Warning: Null value is eliminated by an aggregate or other SET operation.
Tutto questo ci dice è che la colonna conteneva almeno un NULL
valore e che è stato ignorato durante il calcolo dei risultati.
Dati data/ora
Il AVG()
la funzione non accetta espressioni di data/ora.
Supponiamo di avere la seguente tabella:
SELECT PetName, DOB
FROM Pets;
Risultato:
+-----------+------------+ | 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 | +-----------+------------+
Se proviamo a utilizzare AVG()
sul DOB
colonna, riceveremo un errore.
SELECT AVG(DOB) AS Average
FROM Pets;
Risultato:
Msg 8117, Level 16, State 1, Line 1 Operand data type date is invalid for avg operator.
Dati sui caratteri
Il AVG()
anche la funzione non accetta espressioni di stringhe di caratteri.
Ecco cosa succede se proviamo a utilizzare AVG()
nel ProductName
colonna dei nostri Products
tabella (che utilizza un tipo di dati varchar):
SELECT AVG(ProductName) AS Average
FROM Products;
Risultato:
Msg 8117, Level 16, State 1, Line 1 Operand data type varchar is invalid for avg operator.
Il DISTINCT
Parola chiave
Puoi usare il DISTINCT
parola chiave con AVG()
calcolare solo valori distinti. Cioè, se sono presenti valori duplicati, vengono trattati come un valore.
Esempio:
SELECT AVG(DISTINCT ProductPrice) AS DistinctAverage
FROM Products;
Risultato:
+-------------------+ | DistinctAverage | |-------------------| | 56.868333 | +-------------------+
Possiamo vedere che questo risultato è maggiore del risultato che abbiamo ottenuto senza il DISTINCT
parola chiave.
Per ricapitolare, abbiamo ottenuto 52.457142 senza il DISTINCT
parola chiave e 56.868333 con il DISTINCT
parola chiave.
Questo perché ci sono due articoli che condividono lo stesso prezzo (il cacciavite sinistro e il cacciavite destro hanno entrambi un prezzo di 25,99). Pertanto, il AVG()
funzione, se usata con DISTINCT
parola chiave, tratta entrambi i valori come uno e calcola il risultato di conseguenza.
Funzioni della finestra
A seconda del tuo DBMS, potresti essere in grado di utilizzare un OVER
clausola con il tuo AVG()
funzione per creare una funzione finestra.
Una funzione finestra esegue un'operazione di tipo aggregato su un insieme di righe di query. Produce un risultato per ogni riga di query. Ciò è in contrasto con un'operazione di aggregazione, che raggruppa le righe di query in un'unica riga di risultati.
Ecco un esempio per dimostrare il concetto.
Abbiamo già visto i Products
tavolo. Il nostro database ha anche un Customers
tabella e contiene i seguenti dati:
+--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+ | 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 | +--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+
Possiamo recuperare i dati da queste tabelle e presentarli come un set di risultati utilizzando un join.
Possiamo anche usare AVG()
funzione con il OVER
clausola per applicare una funzione finestra ai dati.
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";
Risultato:
+---------------+---------------------------------+----------------+---------------------------+ | VendorName | ProductName | ProductPrice | Average For This Vendor | |---------------+---------------------------------+----------------+---------------------------| | Katty Kittens | Bottomless Coffee Mugs (4 Pack) | 9.99 | 9.990000 | | Mars Supplies | Long Weight (green) | 11.99 | 19.680000 | | Mars Supplies | Long Weight (blue) | 14.75 | 19.680000 | | Mars Supplies | Right handed screwdriver | 25.99 | 19.680000 | | Mars Supplies | Left handed screwdriver | 25.99 | 19.680000 | | Pedal Medals | Straw Dog Box | NULL | 245.000000 | | Pedal Medals | Chainsaw | 245.00 | 245.000000 | | Randy Roofers | Sledge Hammer | 33.49 | 33.490000 | +---------------+---------------------------------+----------------+---------------------------+
In questo caso abbiamo usato il OVER
clausola con il nostro AVG()
funzione per partizionare il risultato in base al nome del fornitore.
In questo modo, siamo stati in grado di restituire le informazioni sui prezzi per ciascun prodotto, nonché il prezzo medio di tutti i prodotti di quel determinato fornitore. Il prezzo medio cambia al variare del fornitore (a meno che più fornitori non abbiano la stessa media), ma rimane lo stesso per tutti i prodotti dello stesso fornitore.
Questo concetto può essere applicato anche ad altre funzioni aggregate in SQL, come SUM()
, MIN()
, MAX()
e COUNT()
.