11th Apr 2023 Tempo di lettura: 9 minuti Come utilizzare CASE WHEN in GROUP BY Nicole Darnley sql group by CASE WHEN Indice Breve rassegna di CASE WHEN Uso di CASE WHEN con GROUP BY Esempio 1: Aggregazioni di categorie personalizzate Esempio 2: CASE WHEN con ELSE in GROUP BY Esempio 3: Dichiarazioni CASE WHEN all'interno di aggregazioni Esempio 4: CASE WHEN in GROUP BY Cosa c'è di nuovo con CASE WHEN e GROUP BY? Scoprite come combinare SQL CASE WHEN e GROUP BY per creare categorie personalizzate nelle vostre query SQL. I dati grezzi, per loro stessa natura, non sono sempre leggibili. Spesso i dati da interrogare sono nella loro forma più informale. Ad esempio, i codici dei diversi reparti aziendali o gli SKU dei prodotti che rappresentano prodotti specifici. A occhio nudo, questi codici non significano nulla, quindi inserirli in un report non è utile per chi li legge. Ci sono anche situazioni in cui i dati grezzi dovrebbero essere arrotolati a livelli superiori per renderli più facilmente digeribili. Ad esempio, un elenco di 50 prodotti può essere arrotolato a 5 categorie di prodotti, rendendo il report molto più facile da leggere e da capire. In questo tipo di situazioni, possiamo usare le istruzioni CASE WHEN e GROUP BY per formattare i dati e aggiungere metadati al nostro set di dati originale. Nel corso di questo articolo analizzeremo il funzionamento di queste dichiarazioni. Per uno sguardo più approfondito su questi concetti, si consiglia di consultare il nostro sito web Come creare semplici report SQL che illustra tutte le sfumature di CASE e GROUP BY. È un ottimo seguito a questo articolo. Per prima cosa, esaminiamo l'istruzione CASE WHEN con alcuni esempi. Se desiderate maggiori informazioni sull'istruzione CASE, leggete il nostro articolo Come usare CASE in SQL. Breve rassegna di CASE WHEN L'istruzione CASE WHEN può essere considerata come la logica if...then della query. Valuta le condizioni e, se le ritiene vere, restituisce un risultato specifico. Ci sono tre elementi importanti per le istruzioni CASE in SQL: CASE WHEN, THEN, e END. Ognuno di questi elementi è necessario, altrimenti la query restituirà un errore. Si inizia l'istruzione con CASE WHEN per definire la condizione logica. Poi si usa THEN per definire il valore se la condizione è vera. Dopo l'ultima istruzione THEN, si usa END per chiudere la clausola. Un'altra clausola opzionale è la clausola ELSE. Se tutte le condizioni logiche dell'istruzione CASE WHEN falliscono, si può usare ELSE per assegnare un valore a questi dati. Si tratta in effetti di una clausola di richiamo. Se i dati non soddisfano tutte le condizioni e non si usa ELSE, i dati restituiranno un valore NULL. Ecco come si presenta la sintassi di CASE WHEN: CASE WHEN product = ‘Shirt’ THEN ‘Clothing’ WHEN product = ‘Hat’ THEN ‘Accessories’ ELSE ‘Other’ END Se il prodotto è una camicia, CASE WHEN la assegna alla categoria Clothing. Se il prodotto è un cappello, CASE WHEN lo assegna alla categoria Accessories. Altrimenti, CASE WHEN assegna il prodotto alla categoria Other. Per illustrare ulteriormente la situazione, si considerino i seguenti dati trovati nella tabella cities tabella: citystateprice_to_income_ratiomortgage_as_pct_of_incomehomeowner_pctpopulation Santa BarbaraCA13.3103.753%88,000 BrooklynNY11.289.930%2,533,862 QueensNY11.191.345%2,271,000 New YorkNY10.485.924%8,468,000 OaklandCA9.477.541%433,800 SunnyvaleCA9.376.545%152,300 San DiegoCA8.266.354%1,382,000 San FranciscoCA9.273.238%815,200 Long BeachCA8.569.641%456,000 BuffaloNY6.55343%276,800 Se volessimo classificare la popolazione di ogni città in bassa, media o alta, eseguiremmo una query: SELECT city, population, CASE WHEN population < 500000 THEN ‘Low’ WHEN population >= 500000 and population < 1500000 THEN ‘Medium’ WHEN population >= 1500000 THEN ‘High’ END as population_level FROM cities In questa query, aggiungiamo una logica condizionale basata sul campo population. Se la popolazione è inferiore a 500.000 abitanti, si assegna il valore Low. Se la popolazione è compresa tra 500.000 e 1.500.000 abitanti, si assegna il valore Medium. Infine, se la popolazione è superiore a 1.500.000, assegniamo il valore High. La colonna viene quindi aliasata come population_level. Il risultato restituito appare così: citypopulationpopulation_level Santa Barbara88,000Low Brooklyn2,533,862High Queens2,271,000High New York8,468,000High Oakland433,800Low Sunnyvale152,300Low San Diego1,382,000Medium San Francisco815,200Medium Long Beach456,000Low Buffalo276,800Low E se volessimo trovare la popolazione media per ogni population_level? In questo scenario, possiamo ottenere questo risultato includendo una clausola di aggregazione e una clausola GROUP BY. Ne daremo una dimostrazione nella prossima sezione. Uso di CASE WHEN con GROUP BY Esempio 1: Aggregazioni di categorie personalizzate Ora che abbiamo la nostra categoria personalizzata population_level, possiamo calcolare diverse metriche per essa. In questo esempio, calcoleremo la popolazione media per ogni population_level. Utilizzeremo la stessa istruzione CASE WHEN di cui sopra, aggiungeremo un'aggregazione per la media e poi GROUP BY utilizzando la stessa sintassi. Eseguiamo questa query: SELECT CASE WHEN population < 500000 THEN ‘Low’ WHEN population >= 500000 and population < 1500000 THEN ‘Medium’ WHEN population >= 1500000 THEN ‘High’ END as population_level, AVG(population) as average_population FROM cities GROUP BY CASE WHEN population < 500000 THEN ‘Low’ WHEN population >= 500000 and population < 1500000 THEN ‘Medium’ WHEN population >= 1500000 THEN ‘High’ END Abbiamo utilizzato la stessa categoria di popolazione della query precedente. Abbiamo aggiunto un calcolo per la popolazione media. Si noti che abbiamo ripetuto la stessa espressione CASE WHEN in SELECT e in GROUP BY. Quando questa query viene eseguita, i dati vengono prima valutati nelle condizioni logiche dell'istruzione CASE WHEN e viene assegnato un valore a population_level. Quindi viene calcolata la media su ciascuno di questi livelli con l'espressione GROUP BY. I risultati restituiti hanno questo aspetto: population_levelaverage_population Low281,380 Medium1,098,600 High4,424,287 Se avete bisogno di un ripasso sulla clausola GROUP BY, leggete questo articolo su GROUP BY in SQL. Esempio 2: CASE WHEN con ELSE in GROUP BY Un altro modo di scrivere questa query sarebbe quello di utilizzare la clausola ELSE. Si definiscono i primi due livelli di popolazione e poi si usa ELSE per inserire ogni altra città in high. Il risultato sarebbe la seguente query: SELECT CASE WHEN population < 500000 THEN ‘Low’ WHEN population >= 500000 and population < 1500000 THEN ‘Medium’ ELSE ‘High’ END as population_level, AVG(population) as average_population FROM cities GROUP BY CASE WHEN population < 500000 THEN ‘Low’ WHEN population >= 500000 and population < 1500000 THEN ‘Medium’ WHEN population >= 1500000 THEN ‘High’ END Non è necessario definire la logica per le città ad alta popolazione; se la città non supera le prime due affermazioni logiche, allora la popolazione è superiore a 1.500.000 abitanti. Esempio 3: Dichiarazioni CASE WHEN all'interno di aggregazioni Possiamo anche inserire le dichiarazioni CASE WHEN all'interno di funzioni aggregate per contare il numero di record che soddisfano determinate condizioni. Continuando con lo stesso esempio, consideriamo come contare il numero di città in ogni population_level. Per questo esempio avremo bisogno di tre istruzioni CASE WHEN separate, una per ogni condizione che abbiamo definito nella nostra istruzione CASE WHEN: low, medium e high. SELECT SUM(CASE WHEN population < 500000 THEN 1 ELSE 0 END) as low_pop_ct, SUM(CASE WHEN population >= 500000 and population < 1500000 THEN 1 ELSE 0 END) as medium_pop_ct, SUM(CASE WHEN population >= 1500000 THEN 1 ELSE 0 END) as high_pop_ct FROM cities Esaminiamo la situazione riga per riga. Nella prima riga, valutiamo se la città ha una popolazione inferiore a 500.000 abitanti. In caso affermativo, assegniamo il valore 1 alla città. In caso contrario, la clausola ELSE assegna il valore 0 alla città. Poi abbiamo avvolto l'intera istruzione CASE WHEN in una SUM(). In questo modo contiamo effettivamente le righe per le città con una popolazione bassa. Ripetiamo questo schema nelle due righe successive, utilizzando le stesse condizioni logiche usate in precedenza per assegnare il valore di medium e high alle città in base alla loro popolazione. Questa query restituirà: low_pop_ctmedium_pop_cthigh_pop_ct 523 Ora abbiamo un conteggio del numero di città che rientrano in ciascuna categoria. Volete saperne di più? Consultate come utilizzare CASE WHEN con SUM() per ulteriori esempi. Esempio 4: CASE WHEN in GROUP BY Vediamo altri esempi di utilizzo di CASE WHEN in GROUP BY. I dati qui sotto sono contenuti nella tabella products. skudescriptionpricestatus 978568952cowl neck sweater59in stock 978548759embroidered v neck blouse49in stock 978125698notched collar button down blazer79in stock 979156258oversized stripe shirt29sale 979145875polka dot maxi dress109back ordered 978457852rib knit t shirt19sale 978333562cropped denim jacket99back ordered 978142154sleeveless midi dress89in stock 979415858utility jumpsuit59sale 978112546scoop neck sweater49in stock Aggiungiamo a questi dati una nuova colonna che contenga product_category. Questo ci permetterà di raggruppare i singoli prodotti in una categoria di livello superiore, in modo da poter calcolare le aggregazioni. Per aggiungere una colonna per product_category, eseguiamo: SELECT *, CASE WHEN description LIKE '%sweater%' OR description LIKE '%blazer%' OR description LIKE '%jacket%' THEN 'Outerwear' WHEN description LIKE '%dress%' OR description LIKE '%jumpsuit%' THEN 'Dresses' WHEN description LIKE '%shirt%' OR description LIKE '%blouse%' THEN 'Tops' END as product_category FROM products Utilizziamo l'operatore LIKE per cercare nel campo della descrizione ogni stringa tra virgolette. L'operatore % significa che può esserci qualsiasi cosa prima o dopo. In effetti, stiamo cercando in ogni descrizione una qualsiasi delle parole chiave elencate nelle dichiarazioni WHEN. I risultati sono mostrati qui sotto: skudescriptionpricestatusproduct_category 978568952cowl neck sweater59in stockOuterwear 978548759embroidered v neck blouse49in stockTops 978125698notched collar button down blazer79in stockOuterwear 979156258oversized stripe shirt29saleTops 979145875polka dot maxi dress109back orderedDresses 978457852rib knit t shirt19saleTops 978333562cropped denim jacket99back orderedOuterwear 978142154sleeveless midi dress89in stockDresses 979415858utility jumpsuit59saleDresses 978112546scoop neck sweater49in stockOuterwear Ora che abbiamo il nostro nuovo campo product_category, possiamo contare il numero di prodotti in ogni categoria utilizzando GROUP BY: SELECT CASE WHEN description LIKE '%sweater%' OR description LIKE '%blazer%' OR description LIKE '%jacket%' THEN 'Outerwear' WHEN description LIKE '%dress%' OR description LIKE '%jumpsuit%' THEN 'Dresses' WHEN description LIKE '%shirt%' OR description LIKE '%blouse%' THEN 'Tops' END as product_category, COUNT(DISTINCT description) as number_of_products FROM products GROUP BY CASE WHEN description LIKE '%sweater%' OR description LIKE '%blazer%' OR description LIKE '%jacket%' THEN 'Outerwear' WHEN description LIKE '%dress%' OR description LIKE '%jumpsuit%' THEN 'Dresses' WHEN description LIKE '%shirt%' OR description LIKE '%blouse%' THEN 'Tops' END product_categorynumber_of_products Outerwear4 Tops3 Dresses3 In questo esempio, abbiamo utilizzato CASE WHEN nella clausola SELECT, ma questo non è sempre necessario. Si può anche eseguire la query precedente senza questa clausola: SELECT COUNT(DISTINCT description) as number_of_products FROM products GROUP BY CASE WHEN description LIKE '%sweater%' OR description LIKE '%blazer%' OR description LIKE '%jacket%' THEN 'Outerwear' WHEN description LIKE '%dress%' OR description LIKE '%jumpsuit%' THEN 'Dresses' WHEN description LIKE '%shirt%' OR description LIKE '%blouse%' THEN 'Tops' END number_of_products 4 3 3 Cosa c'è di nuovo con CASE WHEN e GROUP BY? Come si può vedere, ci sono molti scenari diversi in cui la combinazione delle istruzioni CASE WHEN e GROUP BY è estremamente utile. Esse consentono di aggiungere la logica aziendale ai dati e di calcolare le metriche in base ai nuovi campi di dati definiti. Le istruzioni CASE WHEN possono essere utilizzate sia al di fuori che all'interno delle aggregazioni; seguono la stessa sintassi. Iniziare l'istruzione con CASE WHEN per definire la logica condizionale e poi assegnare i valori con le istruzioni THEN/ELSE. Infine, chiudete il tutto con END. Si consiglia di consultare il nostro corso su Come creare semplici report SQL. Imparerete tutte le sfumature di CASE e GROUP BY e avrete a disposizione problemi pratici da completare! Tags: sql group by CASE WHEN