Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Instrukcja SQL CASE:Co to jest i jakie są najlepsze sposoby jej wykorzystania?

Instrukcja SQL CASE ocenia i zwraca wyniki na podstawie określonych wartości, predykatów i warunków zgodnie ze zdefiniowaną logiką. Załóżmy na przykład, że masz tabelę wyborców z następującymi szczegółami:

  • Identyfikator wyborcy
  • Nazwa
  • ur.

Jeśli szukasz logiki dotyczącej uprawnień do głosowania, byłoby to zależne od wartości w kolumnie DOB.

Jeśli wyborca ​​ma więcej niż 18 lat, może głosować.

Spójrzmy na inny przykład. Wiele razy przechowujemy wartości kolumn w bitach 1 lub 0. Załóżmy, że przechowujesz wartości dostępności produktu jako 1 lub 0. Na przykład:

  • 1 =Produkt jest dostępny
  • 0 =Produkt jest niedostępny

Jeśli spojrzymy na perspektywę bazy danych, dobrą praktyką jest używanie skrótów lub bitów tam, gdzie to możliwe. Jest to korzystne dla optymalizatora zapytań SQL Server podczas przygotowywania zoptymalizowanego planu wykonywania. Jednak z perspektywy aplikacji użytkownik końcowy nie wymaga tych wartości. Klienci muszą tylko sprawdzić, czy produkt jest dostępny, czy nie.

Na poniższym obrazku widzimy zarówno perspektywę bazy danych, jak i aplikacji.

Co robi instrukcja SQL CASE?

Instrukcja CASE w SQL Server ocenia wyrażenie i zwraca wartość na podstawie zdefiniowanych warunków. Dlatego we wcześniejszym przykładzie instrukcje CASE działają tak, jak pokazano poniżej.

Na wyższym poziomie składnia instrukcji SQL CASE jest pokazana poniżej. Tutaj określiliśmy wiele warunków. SQL Server ocenia warunki sekwencyjnie. Gdy warunek zostanie pomyślnie oceniony, zatrzymuje ocenę pozostałych warunków. Jeśli żaden z warunków nie jest spełniony, możemy użyć opcjonalnej instrukcji ELSE, aby zwrócić wartość domyślną. Na przykład, jeśli mamy wartość inną niż 0 i 1 w kolumnie dostępności, otrzymasz dane wyjściowe z bloku kodu ELSE. Wymaga co najmniej jednego zestawu bloków WHEN i THEN. Instrukcja CASE musi kończyć się blokiem END.

Przyjrzyjmy się instrukcji SQL CASE na różnych przykładach.

Uwaga:w tym artykule korzystamy z przykładowej bazy danych firmy Microsoft, AdventureWorks. Możesz pobrać jego kopię zapasową z Microsoft Docs.

Instrukcja SELECT z prostym wyrażeniem CASE

W tego typu instrukcji CASE używamy wyrażeń sprawdzających równość. Poniższe zapytanie implementuje proste wyrażenie CASE.

  • Jeśli wartość w [SalariedFlag] wynosi 1, oznacza to Aktywny pracownik
  • W przypadku wszystkich innych wartości wyświetla dane wyjściowe jako Nieaktywny pracownik
SELECT TOP 5 Nationalidnumber ,
CASE salariedflag
WHEN 1 THEN 'Active Employee'
ELSE 'Inactive Employee'
END AS [Salaried Flag]
FROM [AdventureWorks2019].[HumanResources].[employee]

Możemy określić wiele warunków dla wyrażenia 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]

Standardyzacja danych przy użyciu instrukcji SQL CASE

Zwykle używamy skrótów do przechowywania wartości w tabelach SQL. Standardowe skróty to płeć, kody krajów, status małżeński, popularne nazwy produktów itp.

Załóżmy, że podajemy skróty do przechowywania płci pracowników. Teraz nasza aplikacja powinna wyświetlać wyniki bez żadnych skrótów.

Instrukcje SQL CASE pomagają ujednolicić dane wyjściowe dla zdefiniowanych kryteriów. W poniższym zapytaniu stosujemy następujące warunki:

  • Jeśli wartość płci to M , wyświetl go jako Mężczyzna
  • Jeśli wartość płci to F , wyświetl go jako Kobieta
  • W przypadku innych wartości wyświetl Nieprawidłowy Wartość
SELECT DISTINCT CASE gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
ELSE 'Invalid Value'
END AS Gender
FROM AdventureWorks2019.HumanResources.Employee

Wyszukiwane wyrażenia CASE

W wyszukiwanej instrukcji CASE podajemy wyrażenie CASE zamiast wartości bezpośrednich. Gdy wartość wyrażenia oceni i spełni warunek w klauzuli WHEN, zostanie zwrócona odpowiednia wartość.

Spójrz na poniższe zapytanie SQL. Tutaj zdefiniowaliśmy wyrażenia w klauzuli WHEN dla [ListPrice]. Określa, że ​​koszt produktu wynosi 250 USD i jest oznaczony jako artykuł elektroniczny.

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

W przypadku wspomnianego wcześniej przykładu dotyczącego płci, możemy przepisać instrukcję SQL CASE dla skrótów związanych z płcią, korzystając z przeszukiwanych instrukcji przypadku.

SELECT DISTINCT CASE 
WHEN Gender='M' THEN 'Male'
WHEN Gender='F' THEN 'Female'
ELSE 'Invalid Value'
END AS Gender
FROM AdventureWorks2019.HumanResources.Employee

Korzystanie z instrukcji CASE z klauzulą ​​ORDER BY

Zapytania SQL używają klauzuli ORDER BY do sortowania danych w kolejności rosnącej lub malejącej. Możesz używać instrukcji CASE w połączeniu z klauzulą ​​ORDER BY. Załóżmy, że z tabeli produktów pobieramy [NazwaProduktu] i [CenaListowa]. Chcemy posortować wyniki w następujący sposób:

  • Jeśli cena na liście produktów jest mniejsza niż 2000, chcesz uzyskać wynik w domyślnej kolejności sortowania, tj. rosnąco
  • Jeśli cena katalogowa produktów jest większa niż 2000, sortowanie według klauzuli ORDER BY powoduje sortowanie w porządku malejącym

W tym zapytaniu używamy dwóch instrukcji SQL CASE, aby zaimplementować logikę.

SELECT Name,
ListPrice
FROM Production.Product
ORDER BY CASE
WHEN ListPrice<=2000 THEN ListPrice END 
,CASE WHEN ListPrice >2000 THEN ListPrice END DESC

W poniższym wyniku zapytania możesz zweryfikować sortowanie danych wyświetlane zarówno w kolejności malejącej, jak i rosnącej.

W innym przykładzie załóżmy, że chcemy posortować dane w tabeli pracowników na podstawie następującego warunku:

  • Dla aktywnych pracowników (aktualna flaga =1) dane powinny posortować kolumnę daty zatrudnienia
  • W przypadku nieaktywnych pracowników należy sortować dane według wartości w kolumnie daty urodzenia
SELECT NationalIDNumber,JobTitle,Hiredate,BirthDate, currentflag
FROM AdventureWorks2019.HumanResources.Employee 
ORDER BY 
CASE CURRENTFLAG WHEN 1 THEN HireDate 
else Birthdate 
end

W wyniku zapytania możemy zweryfikować kolejność sortowania danych zdefiniowaną przez klauzulę ORDER BY i instrukcje CASE.

Instrukcja CASE w SQL i funkcjach agregujących

Funkcje agregujące w SQL Server wykonują obliczenia i zwracają pojedynczą wartość. Przykładami funkcji agregujących są MIN, MAX, COUNT, ABG i CHECKSUM.

Załóżmy, że chcemy pobrać liczbę zatrudnionych pracowników dla każdego roku w latach 2007-2010. Powinien wyświetlać wyniki w następującym formacie:

W tym celu używamy funkcji agregującej COUNT w SQL Server.

  • Po pierwsze, funkcja SQL DATEPART filtruje dane według roku. Na przykład DATEPART(YY, Hiredate)=2007 filtruje dane za rok 2007.
  • Następnie używamy instrukcji CASE, aby zwrócić 1, jeśli rok to 2007.
  • Funkcja agregująca licznik zlicza rekordy i wyświetla wyniki.
  • Podobnie zapytanie działa przez pozostałe lata.
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

Podobnie, powiedzmy, że chcemy użyć funkcji agregującej GROUP BY, aby pogrupować wiersze o tej samej kategorii produktu. Możemy określić instrukcję CASE w SQL, aby posortować dane z pogrupowanego zbioru wyników.

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

W powyższym zapytaniu używamy dwóch instrukcji SQL CASE.

  • Pierwsza instrukcja CASE kategoryzuje dane na podstawie wyrażenia zdefiniowanego w cenie katalogowej. Używając tego stwierdzenia CASE, dzielimy produkty na następujące kategorie:
    • Pozycje niedostępne
    • Dobra konsumpcyjne
    • Elementy elektroniczne
    • Przedmioty luksusowe
  • W drugim przypadku używamy funkcji agregującej GROUP BY, aby pogrupować wynik według kategorii
  • Ponadto sortujemy wyniki według NumberOfProducts w kolejności malejącej

Zapobiegaj dzieleniu przez zero za pomocą instrukcji SQL CASE

Błąd dzielenia przez zero występuje, jeśli wartość mianownika wynosi zero. Jeśli wykonasz te ułamki w SQL Server, otrzymasz błąd dzielenia przez zero, jak pokazano poniżej.

Doskonałą praktyką jest pisanie zapytań w taki sposób, aby uniknąć tych typowych błędów. Aby tego uniknąć, używamy logiki ułamkowej wewnątrz instrukcji 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

Zabezpieczyliśmy nasze zapytanie przed błędem dzielenia przez zero. Teraz, ze zmodyfikowaną logiką, jeśli otrzymamy zero w mianowniku, otrzymasz NULL na wyjściu, jak pokazano poniżej.

Przydatne przypomnienia dotyczące instrukcji SQL CASE

  • Instrukcje SQL CASE obsługują do 10 poziomów zagnieżdżania
  • Nie możesz kontrolować przepływu wykonywania instrukcji, funkcji lub procedur za pomocą wyrażeń CASE
  • Zawsze należy używać bloku ELSE, aby w przypadku niespełnienia jakichkolwiek warunków uzyskać wartość domyślną
  • Należy unikać używania sprzecznych warunków w instrukcji SQL CASE. Instrukcja CASE działa sekwencyjnie i przestaje oceniać pierwszy pomyślny warunek

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak mogę przekonwertować tiki na format daty?

  2. Ograniczenie klauzuli IN w SQL Server

  3. Błąd serwera SQL 206:konflikt typu operandu

  4. Jak zamienić wiele znaków w SQL?

  5. Jak utworzyć krok w moim zadaniu agenta programu SQL Server, który będzie uruchamiał mój pakiet SSIS?