В SQL Server, T-SQL CASE
изразът е скаларен израз, който връща стойност въз основа на условна логика. Той оценява списък с условия и връща стойност въз основа на резултата от тези условия...
В някои отношения SQL Server CASE
изразът е подобен на IF...ELSE
. Въпреки това, CASE
ви позволява да проверявате за множество условия, докато IF...ELSE
не прави
Също така, в SQL Server, IF...ELSE
е ключова дума за език за управление на потока, докато CASE
не е. CASE
изразът не може да се използва за контролиране на потока на изпълнение на T-SQL изрази, блокове на оператори, дефинирани от потребителя функции и съхранени процедури.
Двете форми на CASE израз
Има две форми на CASE
израз в SQL Server:
- Прост
CASE
израз - Търсене
CASE
израз
Те са обяснени с примери по-долу.
Формуляр 1 – Прост CASE израз
Простият CASE
израз сравнява израз с набор от прости изрази, за да определи резултата.
Ето основен пример, за да демонстрирате как CASE
изразът работи в SQL Server.
ДЕКЛАРИРАНЕ @stock_ticker varchar(4) ='V';ИЗБЕРЕТЕ Фирма =СЛУЧАЙ @stock_ticker КОГАТО 'AAPL' ПОСЛЕ 'Apple' КОГАТО 'FB' СЛЕД 'Facebook' КОГАТО 'V' СЛЕД 'Visa' ОЩЕ ' Не е в END
на портфолиото
Резултат:
+-----------+| Компания ||-----------|| Виза |+-----------+
В този пример моят CASE
изразът е част от SELECT
изявление. Той проверява за три условия и има ELSE
за да се погрижат за всичко, което не е обхванато от трите условия.
В този случай борсовият тикер V
съвпада с третия WHEN
израз и изразът, предоставен от THEN
се връща.
За да бъде ясно, действителният CASE
изразът е тази част:
СЛУЧАЙ @stock_ticker КОГАТО 'AAPL' СЛЕД 'Apple' КОГА 'FB' ПОСЛЕ 'Facebook' КОГА 'MA' ПОСЛЕ 'Mastercard' КОГАТО 'V' СЛЕД 'Visa' ОЩЕ 'Няма в портфолиото' ENDкод>
Какъв CASE
прави е, той проверява стойността на всеки WHEN
израз спрямо входния израз. В моя пример, @stock_ticker
променливата е входният израз. Следователно, той проверява стойността на всеки WHEN
израз срещу @stock_ticker
променлива.
Когато/ако намери съвпадение, тогава връща израза, предоставен от THEN
.
Моят пример използва три WHEN
изрази, но можеше да е повече, а можеше и по-малко, в зависимост от моите изисквания.
Формуляр 2 – Търсеният CASE израз
Търсеният CASE
Expression оценява набор от булеви изрази, за да определи резултата.
Ето пример за търсен CASE
израз.
ДЕКЛАРИРАЙТЕ @price int =1500;ИЗБЕРЕТЕ Достъпност =СЛУЧАЙ, КОГАТО @price <100 ПОСЛЕ 'Евтино', КОГАТО @price>=100 И @price <500 СЛЕД 'Достъпно' ДРУГО 'Скъп' КРАЙ
Резултат:
+-----------------+| Достъпност ||-----------------|| Скъпо |+-----------------+
Търсен CASE
изразът няма входен израз като простия CASE
израз.
Ще си спомните това в нашия прост CASE
израз, той започна с CASE
@stock_ticker
, и следователно знаехме, че WHEN
всички изрази се оценяваха спрямо стойността на @stock_ticker
.
С търсения CASE
израз, ние не предоставяме входен израз в началото по този начин. Вместо това всеки WHEN
изразът включва булев израз, за който да се оценява.
Пример за база данни
Ето пример, който демонстрира как CASE
изразът може да се използва в рамките на заявка за база данни.
ИЗПОЛЗВАЙТЕ WideWorldImporters;ИЗБЕРЕТЕ CityName КАТО [Град], LatestRecordedPopulation КАТО [Население], Size =CASE WHEN LatestRecordedPopulation <2000000 THEN 'Small City' WHEN LatestRecordedPopulation>=20000000 The LastRecordedPopulation>=20000000 The Last RecordedPopulation AND КРАЙ НА наистина голям град ОТ Application.CitiesWHERE LatestRecordedPopulation> 1000000;
Резултат:
+--------------+--------------+---------------- -+| Град | Население | Размер ||--------------+--------------+---------------- || Бруклин | 2565635 | Големият град || Чикаго | 2695598 | Големият град || Далас | 1197816 | Малък град || Хюстън | 2099451 | Големият град || Лос Анджелис | 3792621 | Наистина голям град || Манхатън | 1619090 | Малък град || Ню Йорк | 8175133 | Наистина голям град || Филаделфия | 1526006 | Малък град || Феникс | 1445632 | Малък град || Queens | 2272771 | Големият град || Сан Антонио | 1327407 | Малък град || Сан Диего | 1307402 | Малък град || Бронкс | 1408473 | Малък град |+--------------+--------------+---------------- -+
Този пример използва търсен CASE
израз за оценка на резултатите от LatestRecordedPopulation
колона на Application.Cities
маса.
Типове данни
В SQL Server типът данни на входния израз и WHEN
изразите трябва да са еднакви или трябва да са имплицитно преобразуване.
Ето какво се случва, ако не са:
ДЕКЛАРИРАЙТЕ @stock_ticker varchar(4) ='V';ИЗБЕРЕТЕ Фирма =СЛУЧАЙ @stock_ticker КОГАТО 1 СЛЕД 'Apple' КОГА 2 СЛЕД 'Facebook' КОГА 3 СЛЕД 'Mastercard' КОГАТО 4 СЛЕД 'Visa' ОЩЕ ' Не е в END
на портфолиото
Резултат:
Съобщение 245, ниво 16, състояние 1, ред 3 Преобразуването не бе успешно при преобразуването на стойността на varchar 'V' в тип данни int.
Ред на оценка
T-SQL CASE
izraz оценява своите условия последователно и спира с първото условие, чието условие е изпълнено.
За да демонстрираме това, нека използваме няколко WHEN
изрази, които споделят една и съща стойност:
ДЕКЛАРИРАНЕ @stock_ticker varchar(4) ='V';ИЗБЕРЕТЕ Фирма =СЛУЧАЙ @stock_ticker КОГА 'V' СЛЕД 'Visa 1' КОГА 'V' СЛЕД 'Visa 2' КОГА 'V' СЛЕД 'Visa 3 ' ELSE 'Няма в портфолиото' END
Резултат:
+-----------+| Компания ||-----------|| Виза 1 |+-----------+
В този случай той спира при първия WHEN
израз.
Може да има случайни сценарии, при които израз се оценява преди CASE
изразът получава резултатите от израза като свой вход. В такива ситуации може да се стигне до грешка. Това може да се случи, ако включите обобщен израз като WHEN
израз.
Поради тази причина Microsoft съветва следното:
Трябва да разчитате само на реда на оценка на условията WHEN за скаларни изрази (включително некорелирани подзаявки, които връщат скалари), а не за агрегатни изрази.
ELSE е по избор
ELSE
аргументът е по избор. Следователно бихме могли да пренапишем нашия пример за „достъпност“ по следния начин:
ДЕКЛАРИРАЙТЕ @price int =1500;ИЗБЕРЕТЕ Достъпност =СЛУЧАЙ, КОГАТО @цена <100 СЛЕД 'Евтино', КОГАТО @цена>=100 И @цена <500 СЛЕД 'Достъпна', КОГАТО @цена>=500 СЛЕД 'Скъпи ' КРАЙ
Резултат:
+-----------------+| Достъпност ||-----------------|| Скъпо |+-----------------+
Въпреки това, имайте предвид, че може да се окажете с NULL
ако пропуснете ELSE
аргумент.
Следният пример води до NULL
:
ДЕКЛАРИРАЙТЕ @price int =1500;ИЗБЕРЕТЕ Достъпност =СЛУЧАЙ, КОГАТО @цена <100 СЛЕД 'Евтино', КОГАТО @цена>=100 И @цена <500 СЛЕД 'Достъпна', КОГАТО @цена>=500 И @цена <1000 СЛЕД 'Скъп' КРАЙ
Резултат:
+-----------------+| Достъпност ||-----------------|| NULL |++-----------------+
В такива случаи винаги можем да добавим ELSE
аргумент, за всеки случай (съжалявам за каламбура!):
ДЕКЛАРИРАЙТЕ @price int =1500;ИЗБЕРЕТЕ Достъпност =СЛУЧАЙ, КОГАТО @цена <100 СЛЕД 'Евтино', КОГАТО @цена>=100 И @цена <500 СЛЕД 'Достъпна', КОГАТО @цена>=500 И @цена <1000 СЛЕД 'Скъп' ОСТАЛО 'Неизвестно' КРАЙ
Резултат:
+-----------------+| Достъпност ||-----------------|| Неизвестно |++-----------------+
Разбира се, този пример вероятно е малко измислен. В края на краищата, няма нужда да ограничавате „скъпо“. Ако нещо е скъпо под $1000, то е скъпо и ако е над $1000.
Но въпросът е, че можете да използвате ELSE
за да хванете всичко, което не е обхванато от WHEN
израз/и.
Вложени CASE изрази
Можете да вложите CASE
изрази, ако е необходимо.
ДЕКЛАРИРАНЕ @price int, @on_sale bit;SET @price =1500;SET @on_sale =1;ИЗБЕРЕТЕ Достъпност =СЛУЧАЙ, КОГАТО @цена <100 ТОГАВА 'Евтино', КОГАТО @цена>=100 ТОГАВА СЛУЧАЙ @on_sale WHEN 0 THEN 'Скъпо (но в момента не е в продажба)' WHEN 1 THEN 'Скъпо (и вече е в продажба!)' END END
Резултат:
+---------------------------------------+| Достъпност ||---------------------------------------|| Скъпо (и вече е в продажба!) |+--------------------------------------- +
Важно е обаче да се отбележи, че само 10 нива на влагане са разрешени за CASE
изрази в SQL Server. Ако се опитате да вложите повече от 10 нива, ще получите грешка.
СЛУЧАЙ в клауза ORDER BY
Както споменахме, T-SQL CASE
изразът може да се използва във всеки израз или клауза, която позволява валиден израз. Следователно можете да го използвате в изрази като SELECT
, АКТУАЛИЗИРАНЕ
, ИЗТРИВАНЕ
и SET
и в клаузи като IN
, КЪДЕ
, ПОРЪЧАЙ ПО
, ГРУПА ПО
и ИМАМ
.
Използване на CASE
израз в ORDER BY
на изявление клаузата може да бъде удобна, когато искате да направите специално изключение за определени стойности, когато поръчвате резултатите си.
Да предположим, че изпълняваме следната заявка срещу таблица, съдържаща музикални жанрове.
ИЗБЕРЕТЕ ЖАНР ОТ MusicGenres ПОРЪЧАЙТЕ ПО Жанр ASC;
Резултат:
+--------+| Жанр ||---------|| Блус || Държава || Хип-хоп || Джаз || Метал || Други || Поп || Рап || Рок |+--------+
Тук подреждаме резултатите по Жанр
колона във възходящ ред.
Това е добре с изключение на едно нещо. Жанрът, наречен Други . Не би ли било хубаво, ако можем да преместим Други до дъното?
Можем да постигнем това с CASE
израз, като вземете горната заявка и я модифицирате, както следва.
ИЗБЕРЕТЕ Жанр ОТ музикални жанрове ПОРЪЧАЙТЕ ПО СЛУЧАЙ Жанр, КОГАТО 'Други' ТОГАВА 1 ОЩЕ 0 КРАЙ ASC, Жанр ASC;
Резултат:
+--------+| Жанр ||---------|| Блус || Държава || Хип-хоп || Джаз || Метал || Поп || Рап || Рок || Други |+--------+
CASE в изявление UPDATE
Ето пример за използване на CASE
израз в UPDATE
изявление.
Да предположим, че имаме следната таблица:
+--------+-----------+----------+---------+| DogId | Име на куче | GoodDog | Вечеря ||--------+-----------+----------+----------|| 1 | Вземи | 1 | NULL || 2 | Пухкави | 0 | NULL || 3 | Размахване | 0 | NULL || 1001 | Брайън | 1 | NULL || 1002 | Рамбо | 0 | NULL || 1003 | BamBam | 1 | NULL |+--------+-----------+-----------+----------+предварително>Наскоро добавихме
Вечеря
колона и все още еNULL
, изчаква стойностите да бъдат вмъкнати.Но стойностите, които трябва да се вмъкнат, ще зависят от стойността на
GoodDog
колона.Можем да използваме
CASE
израз в такъв сценарий.АКТУАЛИЗИРАНЕ НА КОМПЛЕКТ КУЧЕТА Вечеря =СЛУЧАЙ GoodDog WHEN 1 THEN 'Sunday Roast' ELSE 'Храна от самолета' ENDSELECT * ОТ Dogs;
Резултат:
+--------+-----------+-----------+------------ --+| DogId | Име на куче | GoodDog | Вечеря ||--------+-----------+-----------+------------ -|| 1 | Вземи | 1 | Неделно печено || 2 | Пухкави | 0 | Храна на авиокомпанията || 3 | Размахване | 0 | Храна на авиокомпанията || 1001 | Брайън | 1 | Неделно печено || 1002 | Рамбо | 0 | Храна на авиокомпанията || 1003 | BamBam | 1 | Неделно печено |+---------+------------+-----------+----------- --+CASE в изявление INSERT
Можем да вземем таблицата от горния пример и да вмъкнем нова стойност.
И отново можем да се възползваме от
CASE
израз, за да вмъкнете подходящата стойност вВечеря
колона.ДЕКЛАРИРАЙТЕ @DogName nvarchar(60), @GoodDog bit;SET @DogName ='Lazy';SET @GoodDog =0;INSERT INTO Dogs ( DogName, GoodDog, Dinner )ЦЕННОСТИ ( @DogName, @GoodDog, СЛУЧАЙ @GoodDog КОГАТО 1 СЛЕД 'Неделно печено' ОЩЕ 'Храна от самолета' КРАЙ );ИЗБЕРЕТЕ * ОТ Кучета;
Резултат:
+--------+-----------+-----------+------------ --+| DogId | Име на куче | GoodDog | Вечеря ||--------+-----------+-----------+------------ -|| 1 | Вземи | 1 | Неделно печено || 2 | Пухкави | 0 | Храна на авиокомпанията || 3 | Размахване | 0 | Храна на авиокомпанията || 1001 | Брайън | 1 | Неделно печено || 1002 | Рамбо | 0 | Храна на авиокомпанията || 1003 | BamBam | 1 | Неделно печено || 1004 | Мързелив | 0 | Храна на авиокомпанията |+---------+-----------+-----------+----------- --+Този път
CASE
изразът оценяваше стойността на променлива, която току-що сме задали, след което вмъкваше подходящата стойност вВечеря
колона.Израз CASE ли е или CASE израз?
В SQL много неща се наричат „изявление“, когато всъщност са нещо друго. Това също изглежда вярно за T-SQL „
CASE
изявление“.Въпреки че често се нарича
CASE
изявление, по-точно е да го наречемCASE
израз . По този начин се споменава и в документацията на Microsoft.В SQL Server, вместо да бъде само изявление,
CASE
може да се използва във всеки израз или клауза, която позволява валиден израз. Изразът е комбинация от символи и оператори, които се оценяват за получаване на единична стойност на данните.Въпреки това, някои СУБД правят разлика между
CASE
израз иCASE
израз и имат малко по-различен синтаксис за всеки. MySQL прави разлика междуCASE
оператор иCASE
оператор, който по същество е същият катоCASE
израз.