Un'istruzione SQL CASE valuta e restituisce risultati in base a valori, predicati e condizioni particolari secondo la logica definita. Ad esempio, supponi di avere una tabella degli elettori con i seguenti dettagli:
- ID elettore
- Nome
- Data di nascita
Se stavi cercando una logica sull'idoneità al voto, ciò dipenderebbe dai valori nella colonna DOB.
Se l'età di un elettore è maggiore di 18 anni, può votare.
Diamo un'occhiata a un altro esempio. Molte volte, memorizziamo i valori delle colonne nei bit 1 o 0. Supponiamo di memorizzare i valori per la disponibilità di un prodotto come 1 o 0. Ad esempio:
- 1 =Il prodotto è disponibile
- 0 =Il prodotto è esaurito
Se osserviamo la prospettiva del database, è buona norma utilizzare le abbreviazioni oi bit ove possibile. È utile per Query Optimizer di SQL Server nella preparazione del piano di esecuzione ottimizzato. Ma, dal punto di vista dell'applicazione, l'utente finale non richiede questi valori. I clienti devono solo vedere se il prodotto è disponibile o meno.
Nell'immagine sottostante, vediamo sia il database che la prospettiva dell'applicazione.
Cosa fa l'istruzione SQL CASE?
Un'istruzione CASE in SQL Server valuta un'espressione e restituisce un valore in base alle condizioni definite. Pertanto, nell'esempio precedente, le istruzioni CASE funzionano come mostrato di seguito.
A un livello elevato, la sintassi per un'istruzione SQL CASE è mostrata di seguito. Qui, abbiamo specificato più condizioni. SQL Server valuta le condizioni in sequenza. Una volta che una condizione viene valutata correttamente, interrompe la valutazione delle condizioni rimanenti. Se nessuna delle condizioni è soddisfatta, possiamo utilizzare un'istruzione ELSE facoltativa per restituire il valore predefinito. Ad esempio, se abbiamo un valore diverso da 0 e 1 nella colonna disponibilità, ottieni l'output dal blocco di codice ELSE. Richiede almeno un set di blocchi WHEN e THEN. L'istruzione CASE deve terminare con il blocco END.
Esploriamo l'istruzione SQL CASE utilizzando vari esempi.
Nota:in questo articolo utilizziamo il database di esempio Microsoft, AdventureWorks. Puoi scaricare il backup da Microsoft Docs.
L'istruzione SELECT con una semplice espressione CASE
In questo tipo di istruzione CASE, utilizziamo espressioni di controllo di uguaglianza. La query seguente implementa una semplice espressione CASE.
- Se il valore in [SalariedFlag] è 1, mostra il Dipendente attivo
- Per tutti gli altri valori, mostra l'output come Dipendente inattivo
SELECT TOP 5 Nationalidnumber , CASE salariedflag WHEN 1 THEN 'Active Employee' ELSE 'Inactive Employee' END AS [Salaried Flag] FROM [AdventureWorks2019].[HumanResources].[employee]
Possiamo specificare più condizioni per l'istruzione CASE.
SELECT TOP 5 Nationalidnumber , CASE salariedflag WHEN 1 THEN 'Active Employee' WHEN 0 THEN 'Inactive Employee' ELSE 'Invalid Value' END AS [Salaried Flag] FROM [AdventureWorks2019].[HumanResources].[employee]
Standardizzazione dei dati mediante istruzioni SQL CASE
Di solito, utilizziamo le abbreviazioni per memorizzare i valori nelle tabelle SQL. Le abbreviazioni standard sono sesso, prefisso internazionale, stato matrimoniale, nomi di prodotti popolari, ecc.
Supponiamo di specificare le abbreviazioni per memorizzare i sessi dei dipendenti. Ora, la nostra applicazione dovrebbe visualizzare i risultati senza abbreviazioni.
Le istruzioni SQL CASE aiutano a standardizzare l'output per criteri definiti. Nella query seguente, utilizziamo le seguenti condizioni:
- Se il valore del sesso è M , visualizzalo come Maschio
- Se il valore del sesso è F , visualizzalo come Femmina
- Per qualsiasi altro valore, mostra Non valido Valore
SELECT DISTINCT CASE gender WHEN 'M' THEN 'Male' WHEN 'F' THEN 'Female' ELSE 'Invalid Value' END AS Gender FROM AdventureWorks2019.HumanResources.Employee
Dichiarazioni CASE cercate
Nell'istruzione CASE cercata, specifichiamo un'espressione CASE invece dei valori diretti. Una volta che il valore dell'espressione valuta e soddisfa una condizione nella clausola WHEN, viene restituito il valore corrispondente.
Guarda la query SQL di seguito. Qui, abbiamo definito le espressioni nella clausola WHEN per [ListPrice]. Identifica che il costo del prodotto è di $ 250 ed è contrassegnato come un articolo di elettronica.
SELECT ProductNumber, Name, [Product category] = CASE WHEN ListPrice = 0 THEN 'Out of Stock items' WHEN ListPrice > 0 and ListPrice<=100 THEN 'Consumer goods' WHEN ListPrice >100 and ListPrice <= 500 THEN 'Electronics items' WHEN ListPrice >500 and ListPrice < 1500 THEN 'Luxury items' ELSE 'Extra items' END FROM Production.Product order by ListPrice desc
Per l'esempio di genere a cui si è fatto riferimento in precedenza, possiamo riscrivere l'istruzione SQL CASE per le abbreviazioni di genere utilizzando le dichiarazioni del caso ricercate.
SELECT DISTINCT CASE WHEN Gender='M' THEN 'Male' WHEN Gender='F' THEN 'Female' ELSE 'Invalid Value' END AS Gender FROM AdventureWorks2019.HumanResources.Employee
Utilizzo delle istruzioni CASE con la clausola ORDER BY
Le query SQL utilizzano la clausola ORDER BY per l'ordinamento dei dati in ordine crescente o decrescente. È possibile utilizzare le istruzioni CASE insieme alla clausola ORDER BY. Supponiamo che dalla tabella dei prodotti recuperiamo il [NomeProdotto] e il [PrezzoLista]. Vogliamo ordinare i risultati nei seguenti modi:
- Se il prezzo di listino del prodotto è inferiore a 2.000, desideri che il risultato sia nell'ordinamento predefinito, ovvero crescente
- Se il prezzo di listino del prodotto è maggiore di 2.000, l'ordinamento della clausola ORDER BY risulta in un ordine decrescente
In questa query, utilizziamo due istruzioni SQL CASE per implementare la logica.
SELECT Name, ListPrice FROM Production.Product ORDER BY CASE WHEN ListPrice<=2000 THEN ListPrice END ,CASE WHEN ListPrice >2000 THEN ListPrice END DESC
Nell'output della query sottostante, puoi verificare gli ordinamenti dei dati visualizzati sia in ordine decrescente che crescente.
In un altro esempio, supponiamo di voler ordinare i dati nella tabella dipendente in base alla seguente condizione:
- Per i dipendenti attivi (flag corrente =1), i dati devono ordinare la colonna della data di assunzione
- Per i dipendenti inattivi, dovrebbe ordinare i dati secondo i valori nella colonna della data di nascita
SELECT NationalIDNumber,JobTitle,Hiredate,BirthDate, currentflag FROM AdventureWorks2019.HumanResources.Employee ORDER BY CASE CURRENTFLAG WHEN 1 THEN HireDate else Birthdate end
Nell'output della query, possiamo verificare l'ordinamento dei dati definito dalla clausola ORDER BY e dalle istruzioni CASE.
Istruzione CASE in SQL e funzioni aggregate
Le funzioni di aggregazione in SQL Server eseguono calcoli e restituiscono un singolo valore. Esempi di funzioni aggregate sono MIN, MAX, COUNT, ABG e CHECKSUM.
Supponiamo di voler recuperare il conteggio delle assunzioni dei dipendenti per ogni anno dal 2007 al 2010. Dovrebbe visualizzare i risultati nel seguente formato:
A tale scopo, utilizziamo la funzione di aggregazione COUNT in SQL Server.
- In primo luogo, la funzione SQL DATEPART filtra i dati in base all'anno. Ad esempio, DATEPART(YY, Hiredate)=2007, filtra i dati per l'anno 2007.
- Utilizziamo quindi l'istruzione CASE per restituire 1 se l'anno è il 2007.
- La funzione di aggregazione del conteggio conta i record e visualizza i risultati.
- Allo stesso modo, la query funziona per gli anni rimanenti.
SELECT Count(CASE WHEN Datepart(yy, hiredate) = 2007 THEN 1 ELSE NULL END) AS [2007Hires], Count(CASE WHEN Datepart(yy, hiredate) = 2008 THEN 1 ELSE NULL END) AS [2008Hires], Count(CASE WHEN Datepart(yy, hiredate) = 2009 THEN 1 ELSE NULL END) AS [2009Hires], Count(CASE WHEN Datepart(yy, hiredate) = 2009 THEN 1 ELSE NULL END) AS [2010Hires] FROM AdventureWorks2019.HumanResources.Employee
Allo stesso modo, supponiamo di voler utilizzare la funzione di aggregazione GROUP BY per raggruppare righe aventi la stessa categoria di prodotto. Possiamo specificare l'istruzione CASE in SQL per ordinare i dati dal set di risultati raggruppato.
SELECT [Product category] = CASE WHEN listprice = 0 THEN 'Out of Stock items' WHEN listprice > 0 AND listprice <= 100 THEN 'Consumer goods' WHEN listprice > 100 AND listprice <= 500 THEN 'Electronics items' WHEN listprice > 500 AND listprice < 1500 THEN 'Luxury items' ELSE 'Extra items' END, Min(listprice) AS MinPrice, Max(listprice) AS MaxPrice, Count(listprice) AS Numberofproducts FROM production.product GROUP BY CASE WHEN listprice = 0 THEN 'Out of Stock items' WHEN listprice > 0 AND listprice <= 100 THEN 'Consumer goods' WHEN listprice > 100 AND listprice <= 500 THEN 'Electronics items' WHEN listprice > 500 AND listprice < 1500 THEN 'Luxury items' ELSE 'Extra items' END ORDER BY numberofproducts DESC
Nella query precedente, utilizziamo due istruzioni SQL CASE.
- La prima istruzione CASE classifica i dati in base all'espressione definita nel prezzo di listino. Utilizzando questa istruzione CASE, dividiamo i prodotti nelle seguenti categorie:
- Articoli esauriti
- Beni di consumo
- Articoli elettronici
- Articoli di lusso
- Nella seconda istruzione case, utilizziamo la funzione di aggregazione GROUP BY per raggruppare il risultato in base alla categoria
- Inoltre, ordiniamo i risultati secondo NumberOfProducts in ordine decrescente
Impedisci la divisione per zero errori utilizzando le istruzioni SQL CASE
Un errore di divisione per zero si verifica se il valore del denominatore è zero. Se esegui queste frazioni in SQL Server, ti darà l'errore di divisione per zero come mostrato di seguito.
È una pratica eccellente scrivere le tue domande in modo da evitare questi errori comuni. Per evitare ciò, utilizziamo la logica delle frazioni all'interno di un'istruzione CASE.
DECLARE @Student1 INT DECLARE @Student2 INT SET @Student1=100 SET @Student2=0 select CASE WHEN @Student2=0 THEN NULL ELSE @Student1/@Student2 end as StudentMarksRatio
Abbiamo salvaguardato la nostra query dall'errore di divisione per zero. Ora, con la logica modificata, se otteniamo uno zero al denominatore, ottieni NULL nell'output come mostrato di seguito.
Utili promemoria sull'istruzione SQL CASE
- Le istruzioni SQL CASE supportano fino a 10 livelli di annidamento
- Non è possibile controllare il flusso delle esecuzioni di istruzioni, funzioni o procedure utilizzando le espressioni CASE
- Dovresti sempre utilizzare un blocco ELSE in modo che se una qualsiasi condizione non è soddisfatta, ottieni un valore predefinito
- Dovresti evitare di utilizzare condizioni in conflitto nell'istruzione SQL CASE. L'istruzione CASE funziona in sequenza e interrompe la valutazione con la prima condizione riuscita