Data: 10.02.2026

Instrukcja CASE w języku MS SQL Server

Instrukcja CASE w SQL Server – przewodnik z przykładami

Spis treści

Instrukcja CASE w SQL Server umożliwia wprowadzanie logiki warunkowej w zapytaniach, dzięki której możemy np. klasyfikować dane. W artykule prezentujemy praktyczne zastosowania CASE w klauzulach SELECT, WHERE oraz ORDER BY.

Do czego służy instrukcja CASE w SQL Server?

Instrukcja CASE w SQL Server umożliwia zwracanie różnych wartości w zależności od spełnienia określonych warunków – podobnie jak konstrukcja if–else w językach programowania.

Za jej pomocą możemy dynamicznie klasyfikować dane, przekształcać wartości, budować etykiety biznesowe lub sterować sposobem agregacji wyników, bez konieczności modyfikowania struktury tabel.

Składnia prostego wyrażenia CASE

Proste wyrażenie CASE (ang. simple CASE expression) porównuje jedno wyrażenie do zestawu prostych wartości w celu wyznaczenia wyniku. Służy wyłącznie do sprawdzania równości (=). Po słowie CASE podajemy nazwę kolumny lub dowolne poprawne wyrażenie, a po WHEN konkretną, pojedynczą wartość, z którą chcemy ją porównać.

CASE wyrażenie_wejściowe
WHEN wartość_1 THEN wynik_1
WHEN wartość_2 THEN wynik_2
[ ELSE wynik_domyślny ]
END

Elementy składni prostego wyrażenia CASE:

  • słowo kluczowe CASE– podajemy tutaj wyrażenie wejściowe, którym może być: nazwa kolumny, zmienna lub dowolne wyrażenie np. wynik działania matematycznego, którego wartość chcemy sprawdzać. System pobierze wartość z tego miejsca i będzie ją po kolei porównywał z wartościami zapisanymi po słowach WHEN.
  • słowo kluczowe WHEN – podajemy tutaj konkretne, stałe wartości np. liczby, teksty, z którymi chcemy porównać wyrażenie wejściowe zapisane w CASE
  • słowo kluczowe THEN podajemy wartość, która ma zostać zwrócona, jeśli warunek sprawdzany w części WHEN zostanie spełniony
  • słowo kluczowe ELSE – podajemy wartość, która ma zostać zwrócona, jeśli żaden z warunków w części WHEN nie okazał się prawdziwy. Jeśli pominiemy sekcję ELSE, a żaden warunek nie zostanie spełniony, SQL domyślnie zwróci wartość NULL.
  • słowo kluczowe END zamyka instrukcję

W przykładzie wybieramy kolumny FirstName (imię), LastName(nazwisko), Country (kraj) i sprawdzamy, jaki kraj jest w kolumnie Country:

  • jeśli krajem jest USA wstawiamy opis „Dolar ($)”
  • jeśli krajem jest UK wstawiamy opis „Funt (£)”
  • jeśli żaden z warunków nie został spełniony tzn. krajem nie jest ani USA ani UK, wstawiamy „Sprawdzić”
SELECT
LastName,
FirstName,
Country,
CASE Country
WHEN 'USA' THEN 'Dolar ($)'
WHEN 'UK' THEN 'Funt (£)'
ELSE 'Sprawdzić'
END AS WalutaWyplaty
FROM Employees;

Wynik:

LastNameFirstNameCountryWalutaWyplaty
DavolioNancyUSADolar ($)
FullerAndrewUSADolar ($)
LeverlingJanetUSADolar ($)
PeacockMargaretUSADolar ($)
BuchananStevenUKFunt (£)

Składnia przeszukiwanego wyrażenia CASE

Przeszukiwane wyrażenie CASE (ang. Searched CASE expression) ocenia zestaw wyrażeń logicznych (boolean) w celu wyznaczenia wyniku. Pozwala na stosowanie operatorów porównania (>, <, <>) oraz operatorów logicznych (AND, OR).

CASE
WHEN warunek_logiczny_1 THEN wynik_1
WHEN warunek_logiczny_2 THEN wynik_2
[ ELSE wynik_domyślny ]
END

Elementy składni przeszukiwanego wyrażenia CASE:

  • CASE – słowo kluczowe rozpoczynające blok instrukcji warunkowej
  • WHEN warunek_logiczny – podajemy w nim dowolne wyrażenie, które zwraca prawdę (TRUE) lub fałsz (FALSE) np. wiek > 18
  • THEN wynik – wartość, która zostanie zwrócona, jeśli warunek znajdujący się w sekcji WHEN zostanie spełniony
  • ELSE wynik_domyślny (opcjonalne) – wartość, która zostanie zwrócona, jeśli żaden z warunków w WHEN nie zostanie spełniony
  • END – słowo kluczowe kończące blok CASE.

W przykładzie wyświetlamy dane z kolumn OrderID (id zamówienia), ShipCity (miasto wysyłki), Freight (koszt wysyłki) oraz za pomocą instrukcji CASE tworzymy nową kolumnę o nazwie TypKosztu. Wstawimy w niej:

  • słowo „Standard” dla rekordów, które w kolumnie Freight mają wartość mniejszą niż 10
  • słowo „Express” dla rekordów, które w kolumnie Freight mają wartość mniejszą lub równą 50
  • słowo „Premium” dla rekordów, które w kolumnie Freight mają wartość większą niż 50
SELECT
OrderID,
ShipCity,
Freight,
CASE
WHEN Freight < 10.00 THEN 'Standard'
WHEN Freight <= 50.00 THEN 'Express'
WHEN Freight > 50.00 THEN 'Premium'
ELSE 'Błąd'
END AS TypKosztu
FROM Orders;

Wynik:

OrderIDShipCityFreightTypKosztu
10260Köln55,09Premium
10261Rio de Janeiro3,05Standard
10262Albuquerque48,29Express
10263Graz146,06Premium
10264Bräcke3,67Standard

Kolejność sprawdzania warunków w instrukcji CASE

W instrukcji CASE warunki są sprawdzane sekwencyjnie, czyli od góry do dołu, zgodnie z ich kolejnością w kodzie.

Dla danego wiersza silnik SQL analizuje każdy warunek WHEN po kolei i zatrzymuje się w momencie napotkania pierwszego warunku, który zostanie spełniony (zwróci wartość TRUE).

Gdy system dopasuje rekord do danego warunku, przypisuje mu odpowiednią wartość po słowie THEN i przerywa dalsze sprawdzanie dla tego konkretnego wiersza, ignorując pozostałe instrukcje WHEN.

Jeśli żaden z warunków nie zostanie spełniony, system przechodzi do klauzuli ELSE.

CASE w klauzuli SELECT – klasyfikacja i etykiety biznesowe

Umieszczając CASE w klauzuli SELECT, możemy tworzyć dodatkowe kolumny z własnymi kategoriami i opisami.

W przykładzie zamieniamy flagę techniczną na nazwę kanału

SELECT
SalesOrderID,
TotalDue,
OnlineOrderFlag,
CASE
WHEN OnlineOrderFlag = 1 THEN 'On-line'
ELSE 'Stacjonarnie'
END AS SalesChannel
FROM Sales.SalesOrderHeader;

Wynik:

SalesOrderIDTotalDueOnlineOrderFlagSalesChannel
4369544344,82650Stacjonarnie
43696472,31080Stacjonarnie
436973953,98841On-line
436983756,9891On-line

CASE w klauzuli WHERE – filtrowanie zależne od warunku

Instrukcję CASE możemy wykorzystać w klauzuli WHERE do warunkowego filtrowania danych w zależności od wartości danej kolumny.

W przykładzie poniżej:

  • ustalamy maksymalny czas wysyłki (SLA) dla każdego dostawcy (ID dostawcy znajduje się w kolumnie ShipVia)
  • filtrujemy tylko te zamówienia, które zostały wysłane w terminie nieprzekraczającym ustalonego SLA
SELECT OrderID,
ShipVia,
OrderDate,
ShippedDate,
DATEDIFF(DAY, OrderDate, ShippedDate) AS SendDays,
CASE
WHEN ShipVia = 1 THEN 2
WHEN ShipVia = 2 THEN 4
WHEN ShipVia = 3 THEN 7
END AS SendSLA
FROM Orders
WHERE DATEDIFF(DAY, OrderDate, ShippedDate) <=
CASE
WHEN ShipVia = 1 THEN 2
WHEN ShipVia = 2 THEN 4
WHEN ShipVia = 3 THEN 7
END;

Wynik:

OrderIDShipViaOrderDateShippedDateSendDaysSendSLA
1025221996-07-09 00:00:00.0001996-07-11 00:00:00.00024
1025531996-07-12 00:00:00.0001996-07-15 00:00:00.00037
1025621996-07-15 00:00:00.0001996-07-17 00:00:00.00024
1025731996-07-16 00:00:00.0001996-07-22 00:00:00.00067

W przykładzie ta sama instrukcja CASE jest napisana dwukrotnie – raz w klauzuli SELECT, aby wyświetlić dane i drugi raz w klauzuli WHERE, aby przefiltrować. Utrudnia to serwisowanie kodu. Lepiej użyć podzapytania lub CTE.

WITH OrderCalculations AS (
SELECT
OrderID,
ShipVia,
OrderDate,
ShippedDate,
DATEDIFF(DAY, OrderDate, ShippedDate) AS SendDays,
CASE
WHEN ShipVia = 1 THEN 2
WHEN ShipVia = 2 THEN 4
WHEN ShipVia = 3 THEN 7
END AS SendSLA
FROM Orders
)
SELECT *
FROM OrderCalculations
WHERE SendDays <= SendSLA;

Informacje na temat podzapytań znajdziesz w artykule MS SQL podzapytania. Z kolei wyrażenia CTE prezentujemy w artykule MS SQL wyrażenia CTE.

CASE w klauzuli ORDER BY – własne kryteria sortowania

Instrukcja CASE w klauzuli ORDER BY umożliwia zdefiniowanie niestandardowej logiki sortowania.

W przykładzie sortujemy stan magazynowy (UnitsInStock) według następującej kolejności:

  • najpierw te rekordy, które mają stan poniżej 10 sztuk
  • później rekordy, które mają stan poniżej 50 sztuk
  • na koniec rekordy, które mają stan 50 sztuk lub więcej
SELECT
ProductName,
UnitsInStock
FROM Products
ORDER BY
CASE
WHEN UnitsInStock < 10 THEN 1 -- stan poniżej 10
WHEN UnitsInStock < 50 THEN 2 -- stan poniżej 50
ELSE 3 -- stan 50 lub więcej
END,
UnitsInStock;

Wynik:

ProductNameUnitsInStock
Gorgonzola Telino0
Perth Pasties0
Sir Rodney’s Scones3
Louisiana Hot Spiced Okra4

Zastosowanie operatorów ANDOR w instrukcji CASE

Operatory ANDOR umożliwiają w instrukcji CASE łączenie kilku warunków w jedną logiczną decyzję:

  • AND używamy wtedy, gdy wszystkie warunki muszą być spełnione jednocześnie. Cały warunek zwróci wynik TRUE tylko, jeśli każdy ze sprawdzanych warunków jest prawdziwy
  • OR używamy wtedy, gdy wystarczy, aby został spełniony którykolwiek z warunków. Cały warunek zwróci wynik TRUE tylko, jeśli chociaż jeden ze sprawdzanych warunków jest prawdziwy

W przykładzie poniżej za pomocą instrukcji CASE sprawdzamy dla każdego zamówienia, czy nie ma karty kredytowej oraz czy kwota zamówienia jest większa niż 2 tys. Jeśli obydwa warunki są spełnione jednocześnie, zwracana jest wartość „Do weryfikacji”, w przeciwnym razie zwracana jest wartość „OK”.

SELECT
SalesOrderID,
TotalDue,
CreditCardID,
CASE
WHEN TotalDue > 2000
AND CreditCardID IS NULL
THEN 'Do weryfikacji'
ELSE 'OK'
END AS CreditCheckStatus
FROM Sales.SalesOrderHeader;
SalesOrderIDTotalDueCreditCardIDCreditCheckStatus
439233953,98849202OK
439243953,9884NULLDo weryfikacji
439253953,988416992OK

Za pomocą instrukcji CASE sprawdzamy wartość kolumny Color dla każdego wiersza i na podstawie zdefiniowanych warunków przypisujemy nową kategorię.

SELECT
Name,
Color,
CASE
WHEN Color = 'Black' OR Color = 'Red' OR Color = 'White' THEN 'Basic Color'
WHEN Color = 'Silver' OR Color = 'Gold' THEN 'Metallic Color'
WHEN Color IS NULL THEN 'No Color'
ELSE 'Other'
END AS ColorCategory
FROM Production.Product;

Wynik:

NameColorColorCategory
BladeNULLNo Color
LL CrankarmBlackBasic Color
ML CrankarmBlackBasic Color
HL CrankarmBlackBasic Color
Chainring BoltsSilverMetallic Color
Chainring NutSilverMetallic Color

Informacje na temat operatorów ANDOR znajdziesz w artykule MS SQL operatory – praktyczny przewodnik

Agregacja warunkowa – CASE z funkcjami SUMCOUNT

Zastosowanie instrukcji CASE wewnątrz funkcji agregującej umożliwia selektywne wybieranie rekordów, które mają zostać uwzględnione w obliczeniach.

W przykładzie poniżej:

  • zliczamy wszystkie zamówienia z tabeli Orders (kolumna Wszystkie)
  • tworzymy kolumnę Opoznione, w której:
    • instrukcja CASE sprawdza, czy data wysyłki jest późniejsza niż data wymagalności. Jeśli warunek jest spełniony, zwracana jest wartość 1. W przeciwnym przypadku zwracane jest 0.
    • funkcja SUM sumuje wszystkie jedynki, co daje łączną liczbę zamówień opóźnionych
  • tworzymy kolumnę Terminowe, w której:
    • instrukcja CASE sprawdza, czy data wysyłki jest wcześniejsza niż data wymagalności lub jej równa. Jeśli warunek jest spełniony, zwracana jest wartość 1. W przeciwnym przypadku zwracane jest 0.
    • Funkcja SUM sumuje wszystkie jedynki, co daje łączną liczbę zamówień terminowych.
  • tworzymy kolumnę Niewysłane, w której:
    • instrukcja CASE sprawdza czy data wysyłki jest brakująca (NULL). Jeśli warunek jest spełniony, zwracana jest wartość 1. W przeciwnym przypadku zwracane jest 0.
    • Funkcja SUM sumuje wszystkie jedynki, co daje łączną liczbę zamówień niewysłanych.
SELECT
COUNT(*) AS Wszystkie,
SUM(CASE WHEN ShippedDate > RequiredDate THEN 1 ELSE 0 END) AS Opoznione,
SUM(CASE WHEN ShippedDate <= RequiredDate THEN 1 ELSE 0 END) AS Terminowe,
SUM(CASE WHEN ShippedDate IS NULL THEN 1 ELSE 0 END) AS Niewyslane
FROM Orders;

Wynik:

WszystkieOpoznioneTerminoweNiewyslane
8303777221

Zagnieżdżone wyrażenia CASE

Zagnieżdżanie wyrażenia CASE umożliwia budowę wielopoziomowej logiki warunkowej. Zagnieżdżenia robimy, jeśli klasyfikacja danych zależy od więcej niż jednego kryterium, a kolejne warunki są uzależnione od wcześniejszych decyzji.

W przykładzie poniżej z tabeli Production.Product wybieramy produkty, które mają ID równe 1 lub 680 lub 709 i używamy zagnieżdżonej instrukcji CASE, aby oprzeć logikę klasyfikacji produktu na dwóch kryteriach.

W pierwszej instrukcji CASE sprawdzamy, czy kolumna Data zakończenia sprzedaży (SellEndDate) zawiera wartość specjalną NULL:

  • jeśli Data zakończenia sprzedaży zawiera NULL, uruchamia się druga instrukcja CASE
  • jeśli Data zakończenia sprzedaży nie zawiera NULL produkt klasyfikowany jest jako „Wycofany”

Druga instrukcja CASE sprawdza wartość w kolumnie ListPrice:

  • jeśli wartość w kolumnie ListPrice jest większa lub równa 1000, produkt klasyfikowany jest jako „Premium”
  • w przeciwnym wypadku produkt klasyfikowany jest jako „Standard”
SELECT
ProductID,
Name,
ListPrice,
SellEndDate,
CASE
WHEN SellEndDate IS NULL THEN
CASE
WHEN ListPrice >= 1000 THEN 'Premium'
ELSE 'Standard'
END
ELSE 'Wycofany'
END AS ProductClass
FROM Production.Product
WHERE ProductID IN (1,680,709);

Wynik:

ProductIDNameListPriceSellEndDateProductClass
1Adjustable Race0,00NULLStandard
680HL Road Frame – Black, 581431,50NULLPremium
709Mountain Bike Socks, M9,502012-05-29 00:00:00.000Wycofany

Instrukcja CASE w SQL Server a typy danych

W instrukcji CASE wszystkie gałęzie THEN oraz opcjonalna gałąź ELSE muszą zwracać zgodny typ danych, gdyż całe wyrażenie CASE generuje jedną kolumnę o jednym, wspólnym typie wynikowym.

Silnik bazy danych ustala ten typ na podstawie reguł hierarchii typów i w razie potrzeby dokonuje niejawnej konwersji. Jeśli konwersja nie jest możliwa zapytanie zwraca błąd.

Więcej informacji na temat typów danych znajdziesz w artykule Typy danych w MS SQL Server

Jeśli zainteresował Cię temat i chcesz przećwiczyć CASE oraz inne konstrukcje SQL na praktycznych przykładach biznesowych, zajrzyj na nasze kursy SQL

Ewa Barbara Lelusz
Ewa Barbara Lelusz
Analityk biznesowy
Udostępnij wpis:udostępnij Facebookudostępnij Linkedinudostępnij e-mail

Polecane