21st Jul 2022 Tempo di lettura: 13 minuti Cosa sono le funzioni aggregate in SQL e come si usano? Martyna Sławińska sql imparare sql funzioni di aggregazione Indice Come funzionano le funzioni aggregate L'argomento * delle funzioni aggregate La parola chiave DISTINCT L'istruzione CASE Cosa succede ai NULL? Il ruolo di HAVING e GROUP BY con le funzioni aggregate Facciamo pratica! Database di esempio Esempi con COUNT() Esempi con SUM() Esempi con AVG() Esempi con MAX() e MIN() Le funzioni aggregate di SQL come strumento essenziale per la scienza dei dati I dati sono la vostra fonte di conoscenza. E grazie alle funzioni aggregate SQL, potete estrarre dai dati la conoscenza precisa di cui avete bisogno in modo efficiente. Leggete per saperne di più. Le principali funzioni aggregate di SQL sono le seguenti: COUNT(column_name | *) restituisce il numero di righe di una tabella. SUM(column_name) restituisce la somma dei valori di una colonna numerica. AVG(column_name) restituisce il valore medio di una colonna numerica. MIN(column_name) restituisce il valore minimo di una colonna selezionata. MAX(column_name) restituisce il valore massimo di una colonna selezionata. In questo articolo discuteremo di ciascuno di questi elementi con degli esempi. Scoprirete cosa succede a NULLs e ai duplicati quando sono sottoposti a funzioni aggregate. Inoltre, spiegheremo *, la parola chiave DISTINCT e l'istruzione CASE. Iniziamo! Come funzionano le funzioni aggregate Le funzioni aggregate di SQL accumulano i dati di più righe in un'unica riga di riepilogo. Il valore accumulato si basa sui valori della colonna passata come argomento. Possiamo raggruppare le righe usando una clausola GROUP BY e filtrarle ulteriormente usando una clausola HAVING. Un esempio standard è la ricerca del numero di righe di una tabella. In questo caso, aggreghiamo tutte le righe della tabella Libri in un'unica riga. SELECT * FROM Books; IdAuthorTitlePrice 234Anthony MolinaroSQL Cookbook20.00 235Alan BeaulieuLearning SQL25.00 236Donald KnuthThings a Computer Scientist Rarely Talks About25.00 237Donald KnuthThe Art of Computer Programming27.00 SELECT COUNT(*) AS NumberOfBooks FROM Books; NumberOfBooks 4 Facile, no? Utilizzando COUNT(*), è possibile contare il numero di tutte le righe. Potete anche dare un'occhiata agli altri articoli sulle funzioni aggregate di SQL qui e qui. L'argomento * delle funzioni aggregate Se mi chiedete cosa significa * in SQL, vi risponderò che sta per tutti. Viene comunemente utilizzato con l'istruzione SELECT per interrogare tutte le colonne di una determinata tabella. Prendiamo, ad esempio, SELECT * FROM Books, come sopra. L'argomento * può essere utilizzato anche con la funzione aggregata COUNT(). Essa conta tutte le righe di una tabella. Si consideri, ad esempio, SELECT COUNT(*) as NumberOfBooks FROM Books, come sopra. È possibile raggruppare i dati in base a qualche colonna o anche in base a molte colonne. Si veda l'esempio seguente: SELECT Author, COUNT(*) AS NumberOfBooks FROM Books GROUP BY Author; AuthorNumberOfBooks Anthony Molinaro1 Alan Beaulieu1 Donald Knuth2 Conta il numero di libri per autore. L'argomento * si applica solo alla funzione aggregata COUNT(). Per le altre funzioni di aggregazione, è richiesto come argomento una colonna specifica o una combinazione di colonne. La parola chiave DISTINCT La parola chiave DISTINCT indica al database che non si vogliono considerare i valori duplicati. Ad esempio, COUNT(Author) fornisce il numero di tutti gli autori presenti in una tabella. Ma se lo stesso autore compare più volte in una colonna, l'autore viene contato più volte. Date un'occhiata a questo: SELECT COUNT(Author) AS NumberOfAuthors FROM books; NumberOfAuthors 4 Vedete? Conta quattro autori perché Donald Knuth è contato due volte. Cosa succede se aggiungiamo la parola chiave DISTINCT? SELECT COUNT(DISTINCT Author) AS NumberOfAuthors FROM Books; NumberOfAuthors 3 Questa volta utilizziamo la parola chiave DISTINCT. Ora, Donald Knuth viene contato solo una volta. Quando si usa la parola chiave DISTINCT, COUNT() deve avere come argomento una colonna specifica. Restituisce il numero di valori unici memorizzati in quella colonna. Analogamente, è possibile utilizzare la parola chiave DISTINCT con gli argomenti delle funzioni aggregate SUM() e AVG(). Di seguito, sono riportati i risultati dell'esecuzione della funzione SUM() con e senza la parola chiave DISTINCT. SELECT SUM(DISTINCT Price) AS TotalDistinctPrice FROM Books; TotalDistinctPrice 72 SELECT SUM(Price) AS TotalPrice FROM Books; TotalPrice 97 Come si può notare, quando si utilizza la parola chiave DISTINCT, i libri con lo stesso prezzo vengono considerati una sola volta in SUM(). In questo caso, è più sensato utilizzare la funzione SUM() senza la parola chiave DISTINCT. Allo stesso modo, quando si calcola un prezzo medio, è meglio non usare la parola chiave DISTINCT; dovremmo considerare ogni prezzo tutte le volte che appare nella colonna. Si veda cosa succede con AVG(): SELECT AVG(DISTINCT Price) AS TotalDistinctAvg FROM Books; TotalDistinctAvg 24 SELECT AVG(Price) AS TotalAvg FROM Books; TotalAvg 24.25 Per le funzioni aggregate MIN() e MAX(), la parola chiave DISTINCT non fa alcuna differenza. Ma non causa nemmeno errori. Perché? Consideriamo un insieme di numeri {1, 2, 2, 3, 4, 5, 5, 6}. I suoi valori massimi e minimi sono rispettivamente 6 e 1. Con la parola chiave DISTINCT, questo insieme diventa {1, 2, 3, 4, 5, 6}, quindi i valori massimo e minimo sono ancora gli stessi. L'istruzione CASE L'istruzione CASE categorizza e filtra i dati. È come un guardiano per gli argomenti di una funzione aggregata, che decide quali valori far entrare. Vediamo alcuni esempi per illustrare questo concetto. Nella seguente query, usiamo un'istruzione CASE come argomento per la funzione COUNT(). Conta solo i libri il cui prezzo è superiore a 20,00 dollari. SELECT COUNT(CASE WHEN Price > 20 THEN Price END) AS NumberOfExpensiveBooks FROM Books; NumberOfExpensiveBooks 3 Un'istruzione CASE può essere utilizzata come argomento anche per altre funzioni aggregate. Nella query seguente, si sommano i prezzi dei libri che costano esattamente 25,00 dollari. L'istruzione CASE all'interno della funzione SUM() consente di includere nella somma solo i libri con un prezzo di 25,00 dollari. SELECT SUM(CASE WHEN Price = 25 THEN Price END) AS BooksSum FROM Books; BooksSum 50 Ora, nella prossima query, facciamo la media dei prezzi dei libri che costano meno di 26,00 dollari. L'istruzione CASE all'interno della funzione AVG() consente di includere nella media solo i libri con un prezzo inferiore a 26,00 dollari. La funzione AVG() è un argomento della funzione ROUND(), quindi il risultato della funzione AVG() viene arrotondato a due cifre decimali. SELECT ROUND(AVG(CASE WHEN Price < 26 THEN Price END), 2) AS BooksAvg FROM Books; BooksAvg 23.33 Nella prossima query, troviamo il prezzo minimo dei libri su SQL che costano meno di 26,00 dollari. L'istruzione CASE all'interno della funzione MIN() consente di includere nell'insieme solo i libri con un prezzo inferiore a 26,00 dollari. SELECT MIN(CASE WHEN Price < 26 AND Title LIKE '%SQL%' THEN Price END) AS BooksMin FROM Books; BooksMin 20 Quindi, troviamo il prezzo massimo dei libri che costano meno di 25,00 dollari. L'istruzione CASE all'interno della funzione MAX() consente di includere nell'insieme solo i libri con un prezzo inferiore a 25,00 dollari. SELECT MAX(CASE WHEN Price < 25 THEN Price END) AS BooksMax FROM Books; BooksMax 20 Sono certo che si può già immaginare l'esito di queste query! Cosa succede ai NULL? La risposta è semplice. Le funzioni aggregate di SQL ignorano i valori NULL. Consideriamo una tabella aggiornata Books tabella aggiornata. Questa volta abbiamo un prezzo NULL. SELECT * FROM Books; IdAuthorTitlePrice 234Anthony MolinaroSQL Cookbook20.00 235Alan BeaulieuLearning SQL25.00 236Donald KnuthThings a Computer Scientist Rarely Talks About25.00 237Donald KnuthThe Art of Computer ProgrammingNULL COUNT(Price) ora restituisce 3, non 4, e SUM(Price) restituisce 70,00. NULLs viene ignorato in entrambi i casi. È possibile utilizzare le funzioni aggregate anche con le JOIN! Per saperne di più, consultate il nostro articolo sull' uso delle funzioni aggregate SQL con le JOIN. Il ruolo di HAVING e GROUP BY con le funzioni aggregate È facile capire cosa fa una clausola HAVING se si ha familiarità con la clausola WHERE. Una clausola HAVING filtra i valori di uscita delle funzioni aggregate. La clausola GROUP BY consente di dividere i dati in gruppi e di trovare un valore aggregato per ciascun gruppo. Vediamo un esempio. SELECT Author, AVG(Price) AS AvgBookPrice FROM Books GROUP BY Author HAVING AVG(Price) > 20; AuthorAvgBookPrice Alan Beaulieu25 Donald Knuth26 Raggruppiamo i dati in base alla colonna Autore utilizzando la clausola GROUP BY. Quindi, limitiamo i valori di AVG(Price) a un valore superiore a 20 utilizzando la clausola HAVING. Si può provare a usare le clausole WHERE e HAVING insieme per vedere la differenza tra loro. SELECT Author, AVG(Price) AS AvgBookPrice FROM Books WHERE Author LIKE 'A%' GROUP BY Author HAVING AVG(Price) > 20; AuthorAvgBookPrice Alan Beaulieu25 La clausola HAVING è spesso confusa con la clausola WHERE. Ricordate che non è possibile utilizzare funzioni aggregate in una clausola WHERE. Assicuratevi di fare abbastanza pratica e consultate il nostro tutorial su SQL HAVING. Inoltre, date un'occhiata al nostro articolo sull' uso di GROUP BY in SQL per avere maggiori informazioni sulla clausola GROUP BY. Funzioni aggregate SQL o funzioni finestra SQL? O forse entrambe? Date un'occhiata al nostro articolo sulle somiglianze e le differenze tra le due! Facciamo pratica! Non basta leggere. L'SQL richiede molta pratica. Vi proponiamo qui alcuni esempi, in modo che possiate continuare da soli! Prima di addentrarci negli esempi, assicuratevi di avere ben chiari tutti i concetti di SQL Fundamentals e Standard SQL Functions! Database di esempio Di seguito è riportato lo schema del database. Utilizzeremo questo database negli esempi che seguono. Analizziamo il blueprint del database, partendo da sinistra. La tabella Customers memorizza i dati relativi ai clienti. La sua chiave primaria è la colonna CustomerId. La colonna Customers e Orders sono collegate tramite la colonna CustomerId. La tabella Ordini memorizza la data dell'ordine e l'ID del cliente che ha effettuato l'ordine. La sua chiave primaria è la colonna OrderId. Il collegamento tra le tabelle Customers e Orders definisce la relazione tra le tabelle. Un cliente può avere zero o più ordini, ma un ordine può essere assegnato a un solo cliente. Le tabelle Orders e OrderDetails sono collegate tramite la colonna OrderId. Le tabelle Products e OrderDetails sono collegate utilizzando la colonna ProductId. La chiave primaria della tabella OrderDetails è costituita dalle colonne OrderId e ProductId. Un ordine può essere composto da uno o più prodotti. Pertanto, una riga della tabella Orders tabella può essere collegata a una o più righe della tabella OrderDetails tabella. Inoltre, un prodotto può essere presente in zero o più ordini. Di conseguenza, una riga della tabella Products tabella può essere correlata a zero o più righe della tabella. OrderDetails tabella. Inseriamo ora alcuni dati nelle nostre tabelle. La Customers tabella: CustomerIdFirstNameLastNameStreetHouseNoCityCountryEmailPhoneNo 1RachelHartleyBicetown Road602New YorkUSArh@email.com0123456789 2CaitlynRayFriedrichstrasse44BerlinGermanycr@email.com0987654321 3AndrewDuncanLairg Road38LondonNULLad@email.com0567432678 4TaylorJenkinsPark Row106EdinburghUKNULL0876345123 5BenHollandWilliams Avenue252Los AngelesUSAbh@email.com0987456789 La tabella Orders (la colonna della data è nel formato GG-MM-AAAA): OrderIdCustomerIdOrderDate 45110-10-2021 46211-12-2020 47305-05-2021 48409-08-2021 495NULL 50102-06-2021 51207-07-2021 La tabella OrderDetails tabella: OrderIdProductIdQuantity 451002 451013 461001 471024 481013 481035 491042 501003 511011 La tabella Products tabella: ProductIdNameUnitPriceAvailableInStock 100Keyboard30.00300 101USB Drive20.00450 102Mouse20.00500 103Screen100.00450 104Laptop600.00200 Ora siamo pronti per iniziare gli esempi. Esempi con COUNT() Si inizia con la Customers tabella. Scopriamo quanti clienti ci sono per paese. SELECT Country, COUNT(CustomerId) AS NumberOfCustomers FROM Customers GROUP BY Country; CountryNumberOfCustomers NULL1 Germany1 UK1 USA2 Abbiamo selezionato tutti i valori distinti della colonna Country, compreso il valore NULL. La colonna NumberOfCustomers memorizza il numero di clienti per ogni valore della colonna Country. Cosa succede se utilizziamo la colonna Email come argomento della funzione COUNT()? SELECT Country, COUNT(Email) AS NumberOfCustomers FROM Customers GROUP BY Country; CountryNumberOfCustomers NULL1 Germany1 UK0 USA2 Il valore della colonna NumberOfCustomers per il Paese "UK" diventa zero. Questo perché la colonna Email nella tabella Customers tabella è NULL per questo cliente. Vediamo ora un esempio che utilizza le clausole GROUP BY e HAVING. SELECT Country, COUNT(Email) AS NumberOfCustomersWithEmail FROM Customers WHERE Country IS NOT NULL GROUP BY Country HAVING COUNT(Email) > 1; CountryNumberOfCustomersWithEmail USA2 Come prima, selezioniamo i valori della colonna Paese e otteniamo il conteggio dei clienti con e-mail per Paese. Nella clausola WHERE, dichiariamo di non considerare i valori di NULL per la colonna Country. Successivamente, raggruppiamo i dati per Country. Infine, limitiamo i valori della colonna NumberOfCustomersWithEmail a essere maggiori di 1 con una clausola HAVING. Esempi con SUM() Verifichiamo quanto valgono tutti i prodotti disponibili. SELECT SUM(UnitPrice * AvailableInStock) AS AllProductsValue FROM Products; AllProductsValue 193000 In questo caso, la funzione aggregata SUM() crea un valore di UnitPrice * AvailableInStock per ogni riga e poi somma tutti i valori. Supponiamo che ogni ordine di valore superiore a 100,00 dollari abbia diritto a uno sconto. Vogliamo scoprire quali ordini hanno diritto allo sconto. SELECT OrderId, CASE WHEN OrderValue > 100 THEN 1 ELSE 0 END AS QualifiesForDiscount FROM ( SELECT aod.OrderId AS OrderId, SUM(aod.Quantity * ap.UnitPrice) AS OrderValue FROM Products ap JOIN OrderDetails aod ON ap.ProductId = aod.ProductId GROUP BY aod.OrderId ); OrderIdQualifiesForDiscount 451 460 470 481 491 500 510 La query interna seleziona tutti i valori della colonna OrderId e calcola il valore di ogni ordine utilizzando la funzione SUM(). La query esterna utilizza un'istruzione CASE per decidere se l'ordine ha diritto allo sconto (1) o meno (0). Ora, diciamo che tutti i prodotti con un prezzo unitario superiore a 90,00 dollari sono costosi. Scopriamo il valore totale di tutti i prodotti costosi in magazzino. SELECT SUM(CASE WHEN UnitPrice > 90 THEN UnitPrice * AvailableInStock END) AS ExpensiveProductsValue FROM Products; ExpensiveProductsValue 165000 Abbiamo passato una dichiarazione CASE come argomento alla funzione SUM(). Questo argomento assicura che vengano considerate solo le righe con il valore UnitPrice superiore a 90,00 dollari. A parte questo, l'esempio è abbastanza simile al primo di questa sezione. Esempi con AVG() Verifichiamo il prezzo medio di un ordine. SELECT AVG(OrderValue) AS AvgOrderValue FROM ( SELECT aod.OrderId AS OrderId, SUM(aod.Quantity * ap.UnitPrice) AS OrderValue FROM Products ap JOIN OrderDetails aod ON ap.ProductId = aod.ProductId GROUP BY aod.OrderId ); AvgOrderValue 300 La query interna fornisce il valore totale dell'ordine per ogni ordine. La query esterna calcola il valore medio di un ordine. Possiamo anche scoprire la quantità media ordinata per prodotto. SELECT ROUND(AVG(Quantity), 2) AS AvgOrderQuantity FROM OrderDetails; AvgOrderQuantity 2.67 In media, i nostri clienti acquistano da 2 a 3 articoli di un determinato prodotto in un ordine. Vediamo cosa cambia se consideriamo solo i valori unici della colonna Quantity. SELECT ROUND(AVG(DISTINCT Quantity), 2) AS AvgOrderQuantity FROM OrderDetails; AvgOrderQuantity 3 Il valore di output cambia, perché non vengono più considerati i valori duplicati che appaiono nella colonna Quantity della tabella. OrderDetails della tabella. Esempi con MAX() e MIN() Ultimo ma non meno importante! Le funzioni MAX() e MIN() sono piuttosto semplici. Scopriamo gli ordini più vecchi e quelli più recenti. SELECT MIN(OrderDate) AS EarliestOrder, MAX(OrderDate) AS LatestOrder FROM Orders; EarliestOrderLatestOrder 11-12-202010-10-2021 La funzione MIN() restituisce la data più vecchia e la funzione MAX() quella più recente. Possiamo anche identificare i prodotti più economici e quelli più costosi. Per farlo, è possibile effettuare una ricerca nella Products tabella per farlo. SELECT MIN(UnitPrice) AS CheapestProductPrice, MAX(UnitPrice) AS MostExpensiveProductPrice FROM Products; CheapestProductPriceMostExpensiveProductPrice 20600 Scopriamo quanti ordini ci sono per cliente e otteniamo il numero minimo e massimo di ordini per cliente. SELECT MIN(NumberOfOrders) AS MinNumberOfOrders, MAX(NumberOfOrders) AS MaxNumberOfOrders FROM ( SELECT CustomerId, COUNT(OrderID) AS NumberOfOrders FROM Orders GROUP BY CustomerId ); MinNumberOfOrdersMaxNumberOfOrders 12 La query interna seleziona la colonna CustomerId e il numero totale di ordini effettuati da un determinato cliente. La funzione COUNT(OrderId) conta il numero di ordini per cliente. Successivamente, si raggruppano i dati in base alla colonna CustomerId utilizzando una clausola GROUP BY. In questo passaggio, la funzione COUNT(OrderId) conta gli ordini per cliente e non per tutti i clienti insieme. La query esterna seleziona i valori minimi e massimi della colonna NumberOfOrders dalla query interna. Le funzioni aggregate di SQL come strumento essenziale per la scienza dei dati Utilizzando le funzioni aggregate, è possibile trovare facilmente le risposte a domande specifiche, come il numero di clienti o il prezzo medio di un ordine. Le funzioni aggregate di SQL ci permettono di analizzare i dati in modo efficiente. Queste funzioni aggregate SQL di base sono molto utili nella scienza dei dati. Con esse è possibile organizzare i dati nel modo desiderato ed estrarre le informazioni necessarie. Abbiamo esaminato molti esempi con le funzioni aggregate COUNT(), SUM(), AVG(), MIN() e MAX(). Abbiamo anche esaminato esempi di *, della parola chiave DISTINCT e dell'istruzione CASE come argomenti delle funzioni aggregate. Ora siete pronti a creare il vostro database e ad esercitarvi ancora un po'! Tags: sql imparare sql funzioni di aggregazione