1st Dec 2024 Tempo di lettura: 20 minuti 19 esercizi sulle funzioni aggregate Ekre Ceannmor funzioni di aggregazione pratica su sql esercizi online Indice Cosa sono le funzioni aggregate? Perché esercitarsi con le aggregazioni SQL? Il set di dati Esercitatevi con le funzioni aggregate SQL Esercizio 1: Libri nel sistema Esercizio 2: Libri non restituiti Esercizio 3: Libri per genere Esercizio 4: Autori per Paese Esercizio 5: Gamme di pagine per genere Esercizio 5: Gamme di pagine per genere Esercizio 6: Generi di grandi libri Esercizio 7: Generi moderni Esercizio 8: Libri con più autori Esercizio 9: Ultimo prestito di ogni libro Esercizio 10: Prestiti di libri per mese Esercizio 11: Libri popolari Esercizio 12: Libri in ritardo Esercizio 13: Autori medi per genere Esercizio 14: Numero di pagine lette dai clienti Esercizio 15: Utenti senza libri in prestito Esercizio 16: Autori e pubblico Esercizio 17: I libri più vecchi Esercizio 18: Utenti più attivi Esercizio 19: L'autore più produttivo Volete fare più pratica con le funzioni aggregate SQL? Risolvete questi 19 esercizi sulle funzioni aggregate SQL e affinate le vostre abilità in SQL! Esercitatevi a usare le funzioni aggregate con GROUP BY, HAVING, subquery e altro ancora. Include una soluzione e una spiegazione dettagliata per ogni esercizio. Le funzioni aggregate sono una parte importante di SQL. Consentono di calcolare diverse statistiche e di generare report che non sarebbero stati possibili con operazioni su una singola riga, come il filtraggio. È importante esercitarsi spesso con le funzioni aggregate, perché sono una parte fondamentale delle vostre abilità in SQL. Iniziamo! Questo articolo comprende 19 nuovissimi esercizi sulle funzioni aggregate che utilizzano il nostro database di libreria. Tratteremo il raggruppamento con GROUP BY, il filtraggio dei dati con HAVING, l'uso delle funzioni aggregate nelle subquery e l'aggregazione a più livelli. Inoltre, rinfrescheremo le vostre conoscenze sull'utilizzo di JOIN e NULL e sull'ordinamento dei dati in base a diverse statistiche. Quando sarete pronti ad applicare questi concetti in scenari reali, date un'occhiata al nostro corso Basic SQL Reporting ! Copre tutti i concetti relativi alle funzioni aggregate che metterete in pratica in questo articolo, oltre ad altri argomenti importanti come l'uso di CASE WHEN. Vi consigliamo anche di provare le nostre sfide mensili nel nostro percorsoPratica Mensile su SQL . Si tratta di una raccolta di esercizi pratici, pubblicati ogni mese, pensati appositamente per mantenere le vostre competenze in SQL sempre aggiornate. Cosa sono le funzioni aggregate? Lefunzioni aggregate eseguono calcoli su un insieme di valori e restituiscono un singolo valore come risultato. Le funzioni aggregate più comuni sono: SUM() - Calcola la somma di tutti i valori di ciascun gruppo. AVG() - Calcola il valore medio di tutti i valori di ciascun gruppo. COUNT() - Restituisce il numero di valori in ciascun gruppo. MIN() e MAX() - Restituiscono i valori più piccoli e più grandi (rispettivamente) di ciascun gruppo. Queste funzioni sono particolarmente utili per la creazione di report in cui è necessario calcolare varie metriche. Avete bisogno di una spiegazione più dettagliata? Consultate il nostro foglio informativo sulle funzioni aggregate SQL, che illustra tutte le funzioni aggregate, i loro casi d'uso e le loro interazioni con GROUP BY. Perché esercitarsi con le aggregazioni SQL? L'esercizio regolare aiuta a mantenere le proprie capacità, consentendo di analizzare e manipolare i dati in modo più rapido ed efficiente. Con una maggiore pratica, sarete in grado di risolvere problemi più complessi e di ottimizzare meglio le vostre query. Esercitarsi con l'SQL è fondamentale se si vuole intraprendere una carriera come analista di dati, sviluppatore di database o qualsiasi altra posizione che abbia a che fare con molti dati. Consultate il nostro articolo sugli esercizi GROUP BY per affinare ulteriormente le vostre capacità di reporting. Il set di dati Diamo un'occhiata al set di dati con cui lavoreremo per queste domande di esercitazione. Il dataset è composto da cinque tabelle: book author , book_author, patron e book_loan. Ecco lo schema: Le informazioni sui libri sono memorizzate nella tabella book. Essa ha le seguenti colonne: book_id - Un ID univoco per ogni libro e la chiave primaria della tabella. title - Il titolo del libro publication_year - L'anno di pubblicazione del libro. Può essere NULL se non è noto. genre - Il genere del libro, ad esempio "Fantasy" o "Mistero". pages - Il numero di pagine del libro. Ecco un'istantanea dei dati contenuti nella tabella: book_idtitlepublication_yeargenrepages 119841949Political Fiction328 2Animal Farm1945Political Fiction112 3The Hobbit1937Fantasy310 4The Fellowship of the Ring1954Fantasy423 Le informazioni sugli autori sono memorizzate nella tabella author. Ha le seguenti colonne: author_id - Un ID univoco per ogni autore e la chiave primaria della tabella. author_name - Il nome completo o lo pseudonimo dell'autore. country - Il Paese dell'autore. Ecco alcuni dati della tabella: author_idauthor_namecountry 1George OrwellUnited Kingdom 2J.R.R. TolkienUnited Kingdom 3Isaac AsimovUnited States 4Agatha ChristieUnited Kingdom I dati relativi alle persone che prendono in prestito libri dalla biblioteca sono memorizzati nella tabella patron. Essa ha le seguenti colonne: patron_id - Un ID univoco per ogni cliente e la chiave primaria della tabella. patron_name - Il nome completo dell'utente. registration_date - La data di registrazione nel sistema bibliotecario. Ecco alcuni dei dati contenuti nella tabella: patron_idpatron_nameregistration_date 1Alice Johnson2024-01-15 2Bob Smith2024-03-22 3Charlie Brown2024-05-10 4David Wilson2024-06-01 La relazione molti-a-molti tra gli autori e i libri che hanno scritto è memorizzata nella tabella. book_author La tabella ha le seguenti colonne Ha le seguenti colonne: book_author_id - Un ID univoco per ogni coppia libro-autore e la chiave primaria della tabella. author_id - L'ID dell'autore. book_id - L'ID del libro scritto dall'autore. Ecco alcuni dei dati contenuti nella tabella: book_author_idauthor_idbook_id 111 212 323 424 La relazione molti-a-molti tra gli avventori e i libri che hanno preso in prestito è memorizzata nella tabella book_loan tabella. Ha le seguenti colonne: loan_id - Un ID univoco per ogni prestito e la chiave primaria della tabella. book_id - L'ID del libro prestato. patron_id - L'ID del cliente che ha preso in prestito il libro. loan_date - La data di emissione del prestito. due_date - La data di restituzione del libro. return_date - La data effettiva di restituzione del libro. Ecco alcuni dati della tabella: loan_idbook_idpatron_idloan_datedue_datereturn_date 1112024-01-202024-02-202024-02-15 2812024-02-012024-03-012024-02-28 3322024-02-102024-03-102024-03-05 4432024-03-152024-04-102024-04-15 Tornate a questa sezione se dimenticate i nomi delle tabelle o delle colonne durante la risoluzione degli esercizi. Se avete bisogno di suggerimenti per la sintassi, tenete a portata di mano il nostro foglio informativo SQL per l'analisi dei dati. Copre tutti gli strumenti che possono aiutarvi a risolvere questi esercizi. Potete anche scaricarlo in formato PDF e stamparlo, in modo che vi aiuti con gli esercizi futuri! Esercitatevi con le funzioni aggregate SQL Risolvete gli esercizi da soli, poi date un'occhiata alle soluzioni sotto ogni esercizio. Per ogni soluzione ci sono anche ulteriori spiegazioni se vi siete bloccati. Esercizio 1: Libri nel sistema Esercizio: Contare il numero di libri registrati nel database. Soluzione: SELECT COUNT(book_id) FROM book; Spiegazione: Utilizziamo la funzione COUNT() per ottenere il numero di righe nella tabella. book tabella. Si notino due cose. Innanzitutto, la query non ha la clausola WHERE, quindi non vengono filtrate le righe; vengono contate tutte le righe della tabella. In secondo luogo, la query non ha la clausola GROUP BY. Quando si utilizza una funzione aggregata senza GROUP BY, tutte le righe vengono inserite in un gruppo e la funzione viene applicata a tutte le righe di questo gruppo. La query conta quindi tutte le righe della tabella. book tabella. Esercizio 2: Libri non restituiti Esercizio: Contare quanti libri non sono ancora stati restituiti (cioè i libri che non hanno una data di restituzione). Soluzione: SELECT COUNT(loan_id) FROM book_loan WHERE return_date IS NULL; Spiegazione: I libri che non sono stati restituiti non hanno un return_date nella tabella. book_loan tabella; il loro return_date è NULL. Si utilizza questa condizione nella clausola WHERE per selezionare solo i libri che non sono ancora stati restituiti. Utilizziamo la funzione COUNT() per contare il numero di righe nel set di dati risultante. Tenere presente che l'argomento utilizzato con la funzione COUNT() è importante. In questo caso abbiamo inserito come argomento loan_id, che indica al database di contare tutti i valori delle colonne loan_id. In alternativa, avremmo potuto usare COUNT(*) e contare semplicemente tutte le righe nel set di risultati, ottenendo lo stesso risultato. Tuttavia, COUNT(return_date) non sarebbe appropriato: il risultato sarebbe 0. Tutti i return_dates presenti nel risultato sono NULL a causa della condizione return_date IS NULL. Anche in questo caso, non c'è GROUP BY in questa query, quindi la funzione COUNT() conterà tutti i prestiti in cui la data di ritorno è vuota. Esercizio 3: Libri per genere Esercizio: Per ogni genere, indicare il nome del genere e il numero di libri di quel genere. Soluzione: SELECT genre, COUNT(book_id) FROM book GROUP BY genre; Spiegazione: Questo è l'esercizio più elementare di GROUP BY. Dalla tabella bookselezioniamo il genere. Per assicurarci che la funzione COUNT() restituisca un risultato separato per ogni genere, dividiamo il set di dati in gruppi utilizzando GROUP BY genere. In questo modo verranno creati dei gruppi in base ai valori della colonna genre; i libri con lo stesso valore di genere andranno nello stesso gruppo. La funzione COUNT() lavorerà su ogni gruppo separatamente, contando il numero di libri in ogni gruppo. Se avete bisogno di un ripasso su come lavorare con GROUP BY e le funzioni aggregate, consultate la nostra Panoramica completa delle funzioni GROUP BY e aggregate. Esercizio 4: Autori per Paese Esercizio: Per ogni paese, indicare il nome e il numero di autori ad esso associati. Soluzione: SELECT country, COUNT(author_id) FROM author GROUP BY country; Spiegazione: Questo è un altro esercizio di base di GROUP BY. Selezioniamo i dati dalla tabella autore e li raggruppiamo in base ai valori della colonna country. Poi applichiamo COUNT(author_id) a ciascun gruppo per contare gli autori provenienti da questo Paese. Esercizio 5: Gamme di pagine per genere Esercizio: Per ogni genere, mostrare quattro colonne: il nome del genere, il numero minimo e massimo di pagine per i libri di quel genere e difference tra il numero maggiore e minore di pagine di ogni libro. Soluzione: SELECT genre, MIN(pages), MAX(pages), MAX(pages) - MIN(pages) AS difference FROM book GROUP BY genre; Spiegazione: Si tratta di un altro esercizio di GROUP BY di base. Selezioniamo i dati dalla tabella autore e li raggruppiamo in base ai valori della colonna paese. Quindi applichiamo COUNT(author_id) a ciascun gruppo per contare gli autori provenienti da questo paese. Esercizio 5: Gamme di pagine per genere Esercizio: Per ogni genere, mostrare quattro colonne: il nome del genere, il numero minimo e massimo di pagine per i libri di quel genere e la differenza tra il numero maggiore e minore di pagine di ogni libro. Soluzione: Spiegazione: Per ottenere statistiche per ogni genere, raggruppare i dati della tabella in base alla colonna . book dalla tabella in base alla colonna genre. Utilizzare le funzioni aggregate MIN(pages) e MAX(pages) per calcolare il numero minimo e massimo di pagine. Nella terza colonna, utilizzare MIN(pages) - MAX(pages) per calcolare la differenza per ogni gruppo. Infine, rinominate l'ultima colonna in difference utilizzando AS. Esercizio 6: Generi di grandi libri Esercizio: Per ogni genere, mostrare il numero medio di pagine per tutti i libri di quel genere. Mostrare solo i generi in cui il libro medio ha più di 250 pagine. Nominare la colonna delle pagine medie avg_pages. Soluzione: SELECT genre, AVG(pages) AS avg_pages FROM book GROUP BY genre HAVING AVG(pages) >= 250; Spiegazione: Questo esercizio è simile al precedente: si raggruppano i libri per genere e si calcola il numero medio di libri in ciascun genere utilizzando AVG(). Tuttavia, c'è un nuovo elemento: HAVING. HAVING viene utilizzato per filtrare i gruppi e trovare i gruppi per i quali una funzione aggregata soddisfa una certa condizione. Nel nostro caso, cerchiamo i gruppi (generi) in cui il numero medio di pagine è superiore o uguale a 250. Ricordate che HAVING funziona in modo diverso da WHERE. WHERE è usato per filtrare le singole righe prima del raggruppamento, mentre HAVING è usato per filtrare le righe dopo il raggruppamento. Potete leggere la differenza tra HAVING e WHERE nel nostro articolo HAVING vs. WHERE in SQL: Cosa si deve sapere. Esercizio 7: Generi moderni Esercizio: Mostrare l'anno medio di pubblicazione per ogni genere di libri. Arrotondare l'anno a un numero intero. Mostrare solo i generi in cui l'anno medio di pubblicazione è successivo al 1940. Soluzione: SELECT genre, ROUND(AVG(publication_year)) FROM book GROUP BY genre HAVING ROUND(AVG(publication_year)) > 1940; Spiegazione: Questo esercizio è simile al precedente: si raggruppano i libri per genre e si calcola l'anno medio di pubblicazione usando AVG(publication_year). Poi si filtrano i generi con un anno medio di aggregazione superiore al 1940 usando HAVING. Esercizio 8: Libri con più autori Esercizio: Per i libri scritti da più di un autore, indicare il titolo e il numero di autori di ciascun libro. Soluzione: SELECT title, COUNT(author_id) FROM book b JOIN book_author ba ON b.book_id = ba.book_id GROUP BY b.book_id HAVING COUNT(author_id) > 1; Spiegazione: Per prima cosa, dobbiamo trovare gli autori di ciascun libro. A tal fine, uniamo le tabelle book e book_author sulla base del loro comune book_id. In questo modo si uniscono i dati di ogni libro con quelli dei suoi autori: una riga per ogni combinazione libro-autore. Raggruppiamo poi le righe in base a book_id: tutte le righe relative allo stesso libro sono nello stesso gruppo. Pertanto, tutti gli autori di ogni libro saranno nello stesso gruppo. Applichiamo quindi la funzione COUNT(author_id) per contare gli autori in ciascun gruppo. Infine, filtriamo i libri con un solo autore utilizzando HAVING COUNT(author_id) > 1. Esercizio 9: Ultimo prestito di ogni libro Esercizio: Per ogni libro, mostrare il suo title e la data più recente in cui è stato prestato. Nominare la seconda colonna last_loaned. Mostrare NULL nella seconda colonna per tutti i libri che non sono mai stati prestati. Soluzione: SELECT book.title, MAX(book_loan.loan_date) AS last_loaned FROM book LEFT JOIN book_loan ON book.book_id = book_loan.book_id GROUP BY book.book_id, book.title; Spiegazione: Utilizzare un LEFT JOIN per unire le colonne book e book_loan per assicurarsi che anche i libri che non sono mai stati prestati siano inclusi nel set di risultati. Raggruppare i risultati per book_id e book_title. Si noti che non è sufficiente raggruppare i risultati in base al titolo; se due libri hanno lo stesso titolo, verrebbero erroneamente inseriti nello stesso gruppo. Raggruppate per book_id (perché identifica in modo univoco ogni libro) e title (perché SQL lancia un errore se una colonna non aggregata in SELECT non viene inserita in GROUP BY). Potete leggere il nostro articolo 7 Common GROUP BY Errors. Per ottenere l'ultimo loan_date, utilizzare MAX(loan_date). Le date successive vengono trattate come "più grandi". Se non ci sono prestiti per questo libro, tutte le date dei prestiti saranno NULL e la funzione MAX() restituirà NULL per questo libro. Esercizio 10: Prestiti di libri per mese Esercizio: Mostrare quanti prestiti sono stati effettuati ogni mese di ogni anno. Mostrare tre colonne: L'anno e il mese di loan_date come numeri nelle prime due colonne. Nominarle loan_year e loan_month Una colonna che conta quanti libri sono stati prestati in quel mese. Ordinare il risultato in base all'anno e poi al mese, mostrando prima le date più vecchie. Soluzione: SELECT EXTRACT(YEAR FROM loan_date) AS loan_year, EXTRACT(MONTH FROM loan_date) AS loan_month, COUNT(loan_id) FROM book_loan GROUP BY EXTRACT(MONTH FROM loan_date), EXTRACT(YEAR FROM loan_date) ORDER BY loan_year, loan_month; Spiegazione: Utilizziamo EXTRACT(YEAR FROM loan_date) e EXTRACT(MONTH FROM loan_date) per ottenere le parti dell'anno e del mese da loan_date. Utilizziamo ancora EXTRACT() in GROUP BY per raggruppare i prestiti degli stessi mesi. Utilizziamo la funzione COUNT() per calcolare il numero di prestiti effettuati in ciascun mese. Infine, ordiniamo i risultati in base a loan_year e loan_month. Si noti che è possibile utilizzare gli alias delle colonne nell'istruzione ORDER BY. Nella clausola GROUP BY, invece, è ancora necessario utilizzare le funzioni; quando questa clausola viene elaborata, la funzione EXTRACT() (e quindi le nuove colonne) non sono ancora state definite. Per ulteriori informazioni su questo argomento, consultare l'articolo SQL Order of Operations. Esercizio 11: Libri popolari Esercizio: Per ogni libro, mostrate il suo title, il numero di volte che è stato prestato e il numero di clienti diversi che hanno preso in prestito il libro. Nominare le ultime due colonne times_loaned e different_patrons. Soluzione: SELECT title, COUNT(loan_id) AS times_loaned, COUNT(DISTINCT patron_id) AS different_patrons FROM book b LEFT JOIN book_loan bl ON b.book_id = bl.book_id GROUP BY b.title, b.book_id; Spiegazione: Per trovare i prestiti per ogni libro, è necessario unire le tabelle book e book_loan. Utilizzare un LEFT JOIN per assicurarsi che anche i libri che non sono mai stati prestati compaiano nel risultato. Vogliamo raggruppare i prestiti per ogni libro, quindi dobbiamo raggruppare sia per book_id che per il libro title (per lo stesso motivo discusso nell'Esercizio 9). Vogliamo contare il numero di volte in cui il libro è stato prestato e il numero di clienti diversi che hanno preso in prestito il libro. Per farlo, dobbiamo usare la funzione COUNT() due volte. Per prima cosa, utilizziamo COUNT(loan_id) per contare il numero di prestiti del libro. Il secondo uso di COUNT() è più interessante: vogliamo contare i diversi clienti che hanno preso in prestito il libro. Se qualcuno ha preso in prestito lo stesso libro più volte, vogliamo contarlo solo una volta. Per questo usiamo COUNT(DISTINCT patron_id). L'uso di DISTINCT assicura che anche se un cliente ha preso in prestito lo stesso libro più volte, il suo ID sarà contato solo una volta. Per saperne di più, leggere Qual è la differenza tra COUNT(*), COUNT(1), COUNT(column) e COUNT(DISTINCT)? Esercizio 12: Libri in ritardo Esercizio: Per ogni cliente, indicare il nome e la quantità di libri scaduti (cioè con una data di restituzione successiva alla data di scadenza). Soluzione: SELECT patron_name, COUNT(book_id) AS overdue_books FROM patron p LEFT JOIN book_loan bl ON p.patron_id = bl.patron_id AND return_date > due_date GROUP BY p.patron_id, patron_name; Spiegazione: Unire patron e book_loan utilizzando un LEFT JOIN per assicurarsi che anche i clienti che non hanno prestiti scaduti siano inclusi nel risultato. Per selezionare solo i prestiti la cui data di restituzione è successiva alla data di scadenza, utilizzare una condizione di unione combinata: ON p.patron_id = bl.patron_id AND return_date > due_date. La prima parte unisce solo le righe che sono effettivamente correlate. La seconda parte viene utilizzata come filtro aggiuntivo per unire solo i punti in cui return_date > due_date. Si noti che questo è diverso dall'uso di una clausola WHERE più avanti nella query. La clausola WHERE scarterà tutte le righe in cui loan_id IS NULL. Tuttavia, vogliamo mantenere queste righe per includere gli utenti che non hanno libri in ritardo. Raggruppiamo le righe in base a patron_id e patron_name (per gli stessi motivi dell'Esercizio 9). Infine, utilizziamo COUNT(book_id) per contare i libri scaduti per ogni cliente. COUNT() restituirà 0 per gli utenti che non hanno mai effettuato prestiti e per quelli che hanno sempre restituito i libri in tempo. Esercizio 13: Autori medi per genere Esercizio: Per ogni genere, indicare il nome e il numero medio di autori dei libri di quel genere. Dare un nome alla seconda colonna average_authors_per_book Soluzione: WITH number_of_authors AS ( SELECT book_id, COUNT(author_id) AS author_count FROM book_author GROUP BY book_id ) SELECT genre, AVG(author_count) AS average_authors_per_book FROM number_of_authors na JOIN book b ON na.book_id = b.book_id GROUP BY genre; Spiegazione: In questo caso si utilizza una costruzione chiamata espressione di tabella comune (CTE). Per saperne di più sulle CTE, consultate la nostra Guida alle espressioni di tabella comuni. In breve, una CTE consente di creare un insieme di risultati temporanei con nome da utilizzare nella query. Per creare una CTE si utilizza la seguente sintassi: WITH <cte_name> AS (query) Qualsiasi query all'interno della parentesi agirà come una tabella virtuale denominata cte_name e sarà accessibile alla query principale (l'istruzione SELECT dopo la parentesi di chiusura della CTE). Nella CTE, calcoliamo il numero di autori per ogni libro. Selezioniamo book_id e il numero di autori. Si tratta di una query simile a quella dell'Esercizio 8. Nella query esterna, uniamo la nostra CTE number_of_authors con la tabella book per visualizzare il genere di ogni libro. Quindi si utilizzano i generi AVG(author_count) e GROUP BY per ottenere il risultato finale. Se non si vuole usare una CTE, si può ottenere lo stesso risultato usando una sottoquery: SELECT genre, AVG(author_count) AS average_authors_per_book FROM ( SELECT book_id, COUNT(author_id) AS author_count FROM book_author GROUP BY book_id) AS na JOIN book b ON na.book_id = b.book_id GROUP BY genre; Esercizio 14: Numero di pagine lette dai clienti Esercizio: Per ogni cliente, indicare il suo nome e il numero totale di pagine lette (cioè il numero di pagine di tutti i libri che ha preso in prestito). Si presume che abbiano letto ogni libro per intero. Includere tutti i libri, anche quelli non ancora restituiti. Mostrare i risultati solo per gli utenti che hanno letto più di 1.000 pagine. Soluzione: SELECT patron_name, SUM(pages) AS total_pages_read FROM book b JOIN book_loan bl ON b.book_id = bl.book_id JOIN patron p ON p.patron_id = bl.patron_id GROUP BY p.patron_id, p.patron_name HAVING SUM(pages) > 1000; Spiegazione: Unire tre tabelle utilizzando un normale JOIN: patron, book_loan, e book. Utilizzare SUM(pages) per sommare il numero di pagine di tutti i libri presi in prestito dal cliente. Filtrare con HAVING SUM(pages) > 1000 per mostrare solo gli utenti che hanno letto più di 1000 pagine. Nota: poiché si vogliono mostrare gli avventori che hanno letto più di 1.000 pagine, non è necessario usare LEFT JOIN o FULL JOIN in questo caso. Gli utenti che hanno letto 0 pagine saranno comunque filtrati dalla condizione HAVING. Esercizio 15: Utenti senza libri in prestito Esercizio: Mostrare il numero totale di utenti che non hanno mai preso in prestito libri. Soluzione: SELECT COUNT(p.patron_id) FROM patron p WHERE NOT EXISTS ( SELECT * FROM book_loan WHERE patron_id = p.patron_id ); Spiegazione: Per mostrare solo gli avventori che non hanno mai preso in prestito libri, filtrare il risultato con la clausola WHERE NOT EXISTS. Per ogni cliente che non ha mai preso in prestito libri, non esisterà una voce con il nome di quel cliente. book_loan con il suo id. Usare una sottoquery per trovare una serie di prestiti di libri per ogni utente, quindi usare il risultato di questa sottoquery nella clausola WHERE NOT EXISTS. In questo modo ci si assicurerà che tutti i patroni dell'insieme risultante non abbiano prestiti_libraricorrispondenti. Infine, utilizzare la funzione COUNT() per contare i patron_ids selezionati. Esercizio 16: Autori e pubblico Esercizio: Per ogni autore, mostrare quanti mecenati diversi hanno preso in prestito il suo libro. Soluzione: SELECT a.author_name, COUNT(DISTINCT patron_id) AS distinct_patrons FROM author a JOIN book_author ba ON a.author_id = ba.author_id JOIN book b ON b.book_id = ba.book_id LEFT JOIN book_loan bl ON bl.book_id = b.book_id GROUP BY a.author_id, a.author_name; Spiegazione: Unire quattro tabelle: author, book_author, book, e book_loan. Utilizzare un JOIN regolare con le prime tre tabelle e un LEFT JOIN tra libro e libro_prestito. Il LEFT JOIN assicura che anche se il libro non è mai stato prestato, sarà comunque mostrato nel risultato. SELECT Il nome dell'autore e l'utilizzo di COUNT(DISTINCT patron_id) per contare tutti i diversi clienti che hanno preso in prestito i libri. Se i libri dell'autore non sono mai stati presi in prestito, COUNT() restituirà 0. Raggruppare i risultati in base all'ID e al nome dell'autore per evitare gli errori di cui abbiamo parlato in precedenza. Esercizio 17: I libri più vecchi Esercizio: Trovare i libri più vecchi nel database (cioè i libri con il più vecchio publication_year). Mostrare solo due colonne: title e publication_year. Ricordate che può esserci più di un libro con l'anno di pubblicazione più vecchio. Soluzione: SELECT title, publication_year FROM book WHERE publication_year = ( SELECT MIN(publication_year) FROM book ); Spiegazione: Utilizzare una sottoquery per trovare i libri più vecchi. Selezionare solo title e l'anno di pubblicazione dei libri che hanno publication_year uguale all'anno di pubblicazione più basso del sistema. È possibile trovare i primi publication_year con MIN(publication_year). Utilizzare questa espressione all'interno di una sottoquery, quindi confrontare publication_year di ciascun libro con il risultato della sottoquery. Esercizio 18: Utenti più attivi Esercizio: Trovare i nomi di tutti gli utenti che hanno preso in prestito un numero di libri superiore alla media. Mostrare il numero di libri presi in prestito insieme al loro nome. Soluzione: SELECT patron_name, COUNT(*) AS loan_count FROM patron JOIN book_loan ON patron.patron_id = book_loan.patron_id GROUP BY patron_name HAVING COUNT(*) > ( SELECT COUNT(*) FROM book_loan ) / ( SELECT COUNT(*) FROM patron ); Spiegazione: Unire i numeri patron e book_loan e raggruppare i risultati in base al nome e all'ID dell'utente. Per mostrare solo gli utenti che hanno preso in prestito un numero di libri superiore alla media, utilizzare la clausola HAVING che confronta il numero di prestiti dell'utente corrente con il numero medio di libri presi in prestito per utente. La media si ottiene dividendo il numero totale di prestiti per il numero totale di utenti. Poiché / in SQL è una divisione intera (il che significa che il resto viene scartato), utilizzate > (maggiore di) e non >= (maggiore o uguale) per confrontare i valori nella clausola HAVING. Esercizio 19: L'autore più produttivo Esercizio: Trovare l'autore che ha scritto il maggior numero di libri. Soluzione: WITH authors_books_count AS ( SELECT author_id, COUNT(*) AS book_count FROM book_author GROUP BY author_id ) SELECT author_name, book_count FROM author JOIN authors_books_count abc ON author.author_id = abc.author_id WHERE book_count = ( SELECT MAX(book_count) FROM authors_books_count ); Spiegazione: Nella CTE authors_books_count, si trova il numero di libri che ogni autore ha scritto utilizzando il sito id. Nella query esterna, selezioniamo gli autori il cui numero di libri è uguale al numero massimo di libri. Utilizziamo una sottoquery e la funzione MAX() per selezionare il numero massimo di libri dal CTE e confrontarlo con book_count per ogni autore. Volete fare più pratica con le funzioni aggregate SQL? Con questo si conclude questa serie di esercitazioni sulle funzioni aggregate SQL. Ora le vostre competenze sulle funzioni aggregate sono aggiornate! Potete verificare le vostre conoscenze teoriche con queste domande di intervista su GROUP BY. Abbiamo trattato diverse funzioni aggregate, GROUP BY, HAVING e molto altro ancora! Abbiamo fatto pratica con i diversi tipi di JOINs, le subquery e il lavoro con i NULL. Volete saperne di più? Date un'occhiata agli esercizi della nostra enorme traccia Pratica su SQL , che contiene più di 100 ore di esercitazioni su SQL! Oppure provate il nostro Pratica Mensile su SQLche offre un nuovo corso pratico di SQL ogni mese! Tags: funzioni di aggregazione pratica su sql esercizi online