Szukaj…
Wprowadzenie
Wyrażenie CASE służy do implementacji logiki „jeśli-to”.
Składnia
- CASE wyrażenie_wejściowe
KIEDY porównaj 1 TO wynik 1
[KIEDY porównaj 2 TO wynik 2] ...
[INNY wynik X]
KONIEC - WALIZKA
KIEDY warunek 1 TO wynik 1
[KIEDY warunek 2 TO wynik 2] ...
[INNY wynik X]
KONIEC
Uwagi
Proste wyrażenie CASE zwraca pierwszy wynik, którego wartość compareX
jest równa input_expression
.
Przeszukane wyrażenie CASE zwraca pierwszy wynik, którego conditionX
jest prawdziwy.
Szukano CASE w SELECT (odpowiada wyrażeniu boolowskiemu)
Przeszukana CASE zwraca wyniki, gdy wyrażenie logiczne ma wartość PRAWDA.
(Różni się to od prostego przypadku, który może sprawdzić równoważność tylko z wejściem.)
SELECT Id, ItemId, Price,
CASE WHEN Price < 10 THEN 'CHEAP'
WHEN Price < 20 THEN 'AFFORDABLE'
ELSE 'EXPENSIVE'
END AS PriceRating
FROM ItemSales
ID | ItemId | Cena £ | PriceRating |
---|---|---|---|
1 | 100 | 34,5 | KOSZTOWNY |
2) | 145 | 2.3 | TANI |
3) | 100 | 34,5 | KOSZTOWNY |
4 | 100 | 34,5 | KOSZTOWNY |
5 | 145 | 10 | NIEDROGIE |
Użyj CASE, aby policzyć liczbę wierszy w kolumnie zgodnych z warunkiem.
Przypadek użycia
CASE
może być używane w połączeniu z SUM
aby zwrócić liczbę tylko tych elementów, które pasują do wstępnie zdefiniowanego warunku. (Jest to podobne do COUNTIF
w programie Excel).
Sztuczka polega na zwróceniu wyników binarnych wskazujących na dopasowania, więc „1” zwrócone dla pasujących wpisów można zsumować dla liczby całkowitej liczby dopasowań.
Biorąc pod uwagę tę tabelę ItemSales
, powiedzmy, że chcesz poznać całkowitą liczbę przedmiotów, które zostały zaklasyfikowane jako „Drogie”:
ID | ItemId | Cena £ | PriceRating |
---|---|---|---|
1 | 100 | 34,5 | KOSZTOWNY |
2) | 145 | 2.3 | TANI |
3) | 100 | 34,5 | KOSZTOWNY |
4 | 100 | 34,5 | KOSZTOWNY |
5 | 145 | 10 | NIEDROGIE |
Pytanie
SELECT
COUNT(Id) AS ItemsCount,
SUM ( CASE
WHEN PriceRating = 'Expensive' THEN 1
ELSE 0
END
) AS ExpensiveItemsCount
FROM ItemSales
Wyniki:
ItemsCount | ExpensiveItemsCount |
---|---|
5 | 3) |
Alternatywny:
SELECT
COUNT(Id) as ItemsCount,
SUM (
CASE PriceRating
WHEN 'Expensive' THEN 1
ELSE 0
END
) AS ExpensiveItemsCount
FROM ItemSales
SKRÓT SPRAWA w WYBORZE
Stenograficzny wariant CASE
ocenia wyrażenie (zwykle kolumnę) względem szeregu wartości. Ten wariant jest nieco krótszy i oszczędza powtarzania ocenianego wyrażenia w kółko. Można jednak nadal stosować klauzulę ELSE
:
SELECT Id, ItemId, Price,
CASE Price WHEN 5 THEN 'CHEAP'
WHEN 15 THEN 'AFFORDABLE'
ELSE 'EXPENSIVE'
END as PriceRating
FROM ItemSales
Słowo ostrzeżenia. Ważne jest, aby zdawać sobie sprawę z tego, że w przypadku korzystania z krótkiego wariantu całe oświadczenie jest oceniane za każdym razem, WHEN
. Dlatego następujące oświadczenie:
SELECT
CASE ABS(CHECKSUM(NEWID())) % 4
WHEN 0 THEN 'Dr'
WHEN 1 THEN 'Master'
WHEN 2 THEN 'Mr'
WHEN 3 THEN 'Mrs'
END
może dawać wynik NULL
. Jest tak, ponieważ przy każdym WHEN
NEWID()
jest wywoływany ponownie z nowym wynikiem. Równoważny:
SELECT
CASE
WHEN ABS(CHECKSUM(NEWID())) % 4 = 0 THEN 'Dr'
WHEN ABS(CHECKSUM(NEWID())) % 4 = 1 THEN 'Master'
WHEN ABS(CHECKSUM(NEWID())) % 4 = 2 THEN 'Mr'
WHEN ABS(CHECKSUM(NEWID())) % 4 = 3 THEN 'Mrs'
END
Dlatego może pominąć wszystkie przypadki WHEN
i WHEN
wynik NULL
.
SPRAWA w klauzuli ZAMÓW PRZEZ
Możemy użyć 1,2,3 .., aby określić rodzaj zamówienia:
SELECT * FROM DEPT
ORDER BY
CASE DEPARTMENT
WHEN 'MARKETING' THEN 1
WHEN 'SALES' THEN 2
WHEN 'RESEARCH' THEN 3
WHEN 'INNOVATION' THEN 4
ELSE 5
END,
CITY
ID | REGION | MIASTO | DEPARTAMENT | EMPLOYEES_NUMBER |
---|---|---|---|---|
12 | Nowa Anglia | Boston | MARKETING | 9 |
15 | Zachód | San Francisco | MARKETING | 12 |
9 | Środkowy Zachód | Chicago | OBROTY | 8 |
14 | Środkowy Atlantyk | Nowy Jork | OBROTY | 12 |
5 | Zachód | Los Angeles | BADANIA | 11 |
10 | Środkowy Atlantyk | Filadelfia | BADANIA | 13 |
4 | Środkowy Zachód | Chicago | INNOWACJA | 11 |
2) | Środkowy Zachód | Detroit | ZASOBY LUDZKIE | 9 |
Korzystanie z CASE w UPDATE
próbka wzrostu cen:
UPDATE ItemPrice
SET Price = Price *
CASE ItemId
WHEN 1 THEN 1.05
WHEN 2 THEN 1.10
WHEN 3 THEN 1.15
ELSE 1.00
END
Użycie CASE dla wartości NULL zamówionych jako ostatnie
w ten sposób „0” reprezentujące znane wartości są klasyfikowane jako pierwsze, „1” reprezentujące wartości NULL są sortowane według ostatnich:
SELECT ID
,REGION
,CITY
,DEPARTMENT
,EMPLOYEES_NUMBER
FROM DEPT
ORDER BY
CASE WHEN REGION IS NULL THEN 1
ELSE 0
END,
REGION
ID | REGION | MIASTO | DEPARTAMENT | EMPLOYEES_NUMBER |
---|---|---|---|---|
10 | Środkowy Atlantyk | Filadelfia | BADANIA | 13 |
14 | Środkowy Atlantyk | Nowy Jork | OBROTY | 12 |
9 | Środkowy Zachód | Chicago | OBROTY | 8 |
12 | Nowa Anglia | Boston | MARKETING | 9 |
5 | Zachód | Los Angeles | BADANIA | 11 |
15 | ZERO | San Francisco | MARKETING | 12 |
4 | ZERO | Chicago | INNOWACJA | 11 |
2) | ZERO | Detroit | ZASOBY LUDZKIE | 9 |
CASE w klauzuli ORDER BY do sortowania rekordów według najniższej wartości 2 kolumn
Wyobraź sobie, że potrzebujesz sortować rekordy według najniższej wartości jednej z dwóch kolumn. Niektóre bazy danych mogą w tym celu korzystać z ... ORDER BY MIN(Date1, Date2)
funkcji MIN()
lub LEAST()
( ... ORDER BY MIN(Date1, Date2)
), ale w standardowym języku SQL należy użyć wyrażenia CASE
.
Wyrażenie CASE
w poniższym zapytaniu sprawdza kolumny Date1
i Date2
, sprawdza, która kolumna ma niższą wartość, i sortuje rekordy w zależności od tej wartości.
Przykładowe dane
ID | Data 1 | Data 2 |
---|---|---|
1 | 01.01.2017 | 31.01.2017 |
2) | 31.01.2017 | 2017-01-03 |
3) | 31.01.2017 | 02.01.2017 |
4 | 2017-01-06 | 31.01.2017 |
5 | 31.01.2017 | 2017-01-05 |
6 | 2017-01-04 | 31.01.2017 |
Pytanie
SELECT Id, Date1, Date2
FROM YourTable
ORDER BY CASE
WHEN COALESCE(Date1, '1753-01-01') < COALESCE(Date2, '1753-01-01') THEN Date1
ELSE Date2
END
Wyniki
ID | Data 1 | Data 2 |
---|---|---|
1 | 01.01.2017 | 31.01.2017 |
3) | 31.01.2017 | 02.01.2017 |
2) | 31.01.2017 | 2017-01-03 |
6 | 2017-01-04 | 31.01.2017 |
5 | 31.01.2017 | 2017-01-05 |
4 | 2017-01-06 | 31.01.2017 |
Wyjaśnienie
Jak widać wiersz z Id = 1
to po pierwsze, że ponieważ Date1
mają najniższy rekord z całej tabeli 2017-01-01
wiersz gdzie Id = 3
jest drugim, bo Date2
równa 2017-01-02
czyli drugą najniższą wartość z tabeli i tak dalej.
Date1
więc rekordy od 2017-01-01
do 2017-01-06
rosnąco i nie przejmujemy się, w której kolumnie Date1
lub Date2
są tymi wartościami.