Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Istruzione SQL CASE:cos'è e quali sono i modi migliori per utilizzarla?

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