I SQL Server, T-SQL CASE
udtryk er et skalært udtryk, der returnerer en værdi baseret på betinget logik. Den evaluerer en liste over betingelser og returnerer en værdi baseret på resultatet af disse betingelser.
På nogle måder, SQL Server CASE
udtryk ligner IF...ELSE
. Dog CASE
giver dig mulighed for at tjekke for flere forhold, hvorimod IF...ELSE
gør ikke.
Også i SQL Server, IF...ELSE
er et kontrol-af-flow sprog søgeord, hvorimod CASE
er ikke. CASE
udtryk kan ikke bruges til at kontrollere udførelsesstrømmen af T-SQL-sætninger, sætningsblokke, brugerdefinerede funktioner og lagrede procedurer.
De 2 CASE-udtryk
Der er to former for CASE
udtryk i SQL Server:
- Simpel
CASE
udtryk - Søgte i
CASE
udtryk
Disse er forklaret med eksempler nedenfor.
Form 1 – Det simple CASE-udtryk
Den simple CASE
udtryk sammenligner et udtryk med et sæt simple udtryk for at bestemme resultatet.
Her er et grundlæggende eksempel for at demonstrere, hvordan en CASE
udtryk virker i SQL Server.
DECLARE @stock_ticker varchar(4) ='V';SELECT Company =CASE @stock_ticker NÅR 'AAPL' SÅ 'Apple' NÅR 'FB' SÅ 'Facebook' NÅR 'V' SÅ 'Visa' ELLES ' Ikke i porteføljen' END
Resultat:
+------------+| Firma ||--------|| Visa |+-----------+
I dette eksempel er min CASE
udtryk er en del af en SELECT
udmelding. Den tjekker for tre forhold og har en ELSE
at tage højde for alt, der ikke er dækket af de tre betingelser.
I dette tilfælde er aktieindekset V
matcher den tredje WHEN
udtryk og udtrykket leveret af THEN
er returneret.
For at være klar, den faktiske CASE
udtryk er denne del:
CASE @stock_ticker NÅR 'AAPL' SÅ 'Apple' NÅR 'FB' SÅ 'Facebook' NÅR 'MA' SÅ 'Mastercard' NÅR 'V' SÅ 'Visa' ELLES 'Ikke i porteføljen' SLUT<
Hvilken CASE
gør det, tjekker den værdien af hver HVORNÅR
udtryk mod inputudtrykket. I mit eksempel er @stock_ticker
variabel er input-udtrykket. Derfor tjekker den værdien af hver HVORNÅR
udtryk mod @stock_ticker
variabel.
Når/hvis den finder et match, returnerer den udtrykket leveret af THEN
.
Mit eksempel bruger tre WHEN
udtryk, men det kunne have været flere og det kunne have været mindre, alt efter mine krav.
Formular 2 – Det søgte CASE-udtryk
Den søgte CASE
udtryk evaluerer et sæt boolske udtryk for at bestemme resultatet.
Her er et eksempel på en søgt CASE
udtryk.
DECLARE @price int =1500;SELECT Affordability =CASE WHEN @price <100 SÅ 'Billig' NÅR @price>=100 OG @price <500 SÅ 'Overkommelig' ELLER 'Dyr' SLUT
Resultat:
+----------------+| Overkommelig pris ||----------------|| Dyrt |+-----------------+
En søgt CASE
udtryk har ikke et input-udtryk som den simple CASE
udtryk.
Du husker det i vores simple CASE
udtryk, det startede med CASE
@stock_ticker
, og derfor vidste vi, at WHEN
udtryk blev alle evalueret mod værdien af @stock_ticker
.
Med den søgte CASE
udtryk, giver vi ikke et input-udtryk i starten på den måde. I stedet skal hver HVORNÅR
udtryk inkluderer et boolesk udtryk, som der skal evalueres i forhold til.
Et databaseeksempel
Her er et eksempel, der viser, hvordan CASE
udtryk kan bruges i en databaseforespørgsel.
BRUG WideWorldImporters;VÆLG bynavn SOM [By], LatestRecordedPopulation AS [Population], Størrelse =CASE WHEN LatestRecordedPopulation <2000000 SÅ 'Lille by' NÅR SenestRecordedPopulation>=20000000 '000000000000000000000000000000000000000000000000000000000B. Really Big City' END FROM Application.CitiesWHERE LatestRecordedPopulation> 1000000;
Resultat:
+--------------+-------------+---------------- -+| By | Befolkning | Størrelse ||--------------+--------------+---------------- || Brooklyn | 2565635 | Storby || Chicago | 2695598 | Storby || Dallas | 1197816 | Lille By || Houston | 2099451 | Storby || Los Angeles | 3792621 | Virkelig storby || Manhattan | 1619090 | Lille By || New York | 8175133 | Virkelig storby || Philadelphia | 1526006 | Lille By || Phoenix | 1445632 | Lille By || Dronninger | 2272771 | Storby || San Antonio | 1327407 | Lille By || San Diego | 1307402 | Lille By || Bronx | 1408473 | Lille by |+--------------+--------------+---------------- -+
Dette eksempel bruger en søgt CASE
udtryk for at evaluere resultaterne fra LatestRecordedPopulation
kolonne i Application.Cities
bord.
Datatyper
I SQL Server, datatypen for inputudtrykket og WHEN
udtryk skal være det samme eller skal være en implicit konvertering.
Her er, hvad der sker, hvis de ikke er det:
DECLARE @stock_ticker varchar(4) ='V';SELECT Company =CASE @stock_ticker NÅR 1 SÅ 'Apple' NÅR 2 SÅ 'Facebook' NÅR 3 SÅ 'Mastercard' NÅR 4 SÅ 'Visa' ELLES ' Ikke i porteføljen' END
Resultat:
Besked 245, niveau 16, tilstand 1, linje 3 Konvertering mislykkedes ved konvertering af varchar-værdien 'V' til datatype int.
Evalueringsrækkefølge
T-SQL CASE
expression evaluerer sine betingelser sekventielt og stopper med den første betingelse, hvis betingelse er opfyldt.
For at demonstrere dette, lad os bruge flere HVORNÅR
udtryk, der deler samme værdi:
DECLARE @stock_ticker varchar(4) ='V';SELECT Company =CASE @stock_ticker NÅR 'V' SÅ 'Visa 1' NÅR 'V' SÅ 'Visa 2' NÅR 'V' SÅ 'Visa 3' ' ELSE 'Ikke i porteføljen' END
Resultat:
+------------+| Firma ||--------|| Visa 1 |+-----------+
I dette tilfælde stoppede den ved den første HVORNÅR
udtryk.
Der kan være lejlighedsvise scenarier, hvor et udtryk evalueres før en CASE
udtryk modtager resultaterne af udtrykket som input. I sådanne scenarier kan du ende med en fejl. Dette kan ske, hvis du inkluderer et samlet udtryk som WHEN
udtryk.
Af denne grund anbefaler Microsoft, at:
Du bør kun afhænge af evalueringsrækkefølgen af WHEN-betingelserne for skalære udtryk (herunder ikke-korrelerede underforespørgsler, der returnerer skalarer), ikke for aggregerede udtryk.
ANDET er valgfrit
ELSE
argument er valgfrit. Derfor kunne vi omskrive vores "overkommelige" eksempel som følger:
DECLARE @price int =1500;SELECT Affordability =CASE NÅR @price <100 SÅ 'Billig' NÅR @price>=100 OG @price <500 SÅ 'Affordable' NÅR @price>=500 SÅ 'Dyrt' ' SLUT
Resultat:
+----------------+| Overkommelig pris ||----------------|| Dyrt |+-----------------+
Vær dog opmærksom på, at du kan ende med NULL
hvis du udelader ELSE
argument.
Følgende eksempel resulterer i NULL
:
DECLARE @price int =1500;SELECT Affordability =CASE NÅR @price <100 SÅ "Billig" NÅR @price>=100 OG @price <500 SÅ "Affordable" NÅR @price>=500 OG @price <1000 SÅ 'Dyr' SLUT
Resultat:
+----------------+| Overkommelig pris ||----------------|| NULL |+-----------------+
I sådanne tilfælde kunne vi altid tilføje en ELSE
argument, for en sikkerheds skyld (undskyld ordspillet!):
DECLARE @price int =1500;SELECT Affordability =CASE NÅR @price <100 SÅ "Billig" NÅR @price>=100 OG @price <500 SÅ "Affordable" NÅR @price>=500 OG @price <1000 SÅ 'Dyrt' ELLES 'Ukendt' SLUT
Resultat:
+----------------+| Overkommelig pris ||----------------|| Ukendt |+-----------------+
Dette eksempel er ganske vist nok en smule fortænkt. Når alt kommer til alt, er der ingen grund til at sætte et loft over "dyrt". Hvis noget er dyrt til under 1000 USD, så er det også dyrt, hvis det er over 1000 USD.
Men pointen er, at du kan bruge ELSE
at fange noget, der ikke er dækket af HVORNÅR
udtryk/s.
Indlejrede CASE-udtryk
Du kan indlejre CASE
udtryk, hvis det kræves.
DECLARE @price int, @on_sale bit;SET @price =1500;SET @on_sale =1;SELECT Affordability =CASE WHEN @price <100 THEN 'Billig' NÅR @price>=100 THEN CASE @on_sale NÅR 0 SÅ "Dyrt (men det er ikke til salg i øjeblikket)" NÅR 1 SÅ "Dyrt (og det er allerede til salg!)" SLUT SLUT
Resultat:
+----------------------------------------------+| Overkommelig pris ||----------------------------------------------|| Dyrt (og det er allerede til salg!) |+--------------------------------------------------- +
Det er dog vigtigt at bemærke, at kun 10 niveauer af indlejring er tilladt for CASE
udtryk i SQL Server. Hvis du prøver at indlejre mere end 10 niveauer, får du en fejl.
CASE i en ORDER BY-klausul
Som nævnt er T-SQL CASE
udtryk kan bruges i enhver sætning eller klausul, der tillader et gyldigt udtryk. Derfor kan du bruge det i sætninger såsom SELECT
, OPDATERING
, SLET
og SET
, og i klausuler såsom IN
, HVOR
, BEstil efter
, GRUPPER EFTER
og HAVING
.
Brug af en CASE
udtryk i en sætnings ORDER BY
klausul kan være praktisk, når du vil gøre en særlig undtagelse for bestemte værdier, når du bestiller dine resultater.
Antag, at vi kører følgende forespørgsel mod en tabel, der indeholder musikgenrer.
VÆLG Genre FRA MusicGenresORDER BY Genre ASC;
Resultat:
+--------+| Genre ||--------|| Blues || Land || Hip Hop || Jazz || Metal || Andet || Pop || Rap || Rock |+--------+
Her sorterer vi resultaterne efter Genre
kolonne i stigende rækkefølge.
Det er fint bortset fra én ting. Genren kaldet Andet . Ville det ikke være rart, hvis vi kunne flytte Andet til bunden?
Vi kan opnå dette med CASE
udtryk ved at tage ovenstående forespørgsel og ændre den som følger.
VÆLG GenreFRA musikgenrerORDER BY CASE Genre NÅR 'Andet' SÅ 1 ANDET 0 END ASC, Genre ASC;
Resultat:
+--------+| Genre ||--------|| Blues || Land || Hip Hop || Jazz || Metal || Pop || Rap || Rock || Andet |+---------+
CASE i en OPDATERINGSerklæring
Her er et eksempel på brug af en CASE
udtryk i en OPDATERING
erklæring.
Antag, at vi har følgende tabel:
+--------+-----------+-----------+--------+| DogId | Hundenavn | GoodDog | Aftensmad ||--------+------------+-----------+--------|| 1 | Hent | 1 | NULL || 2 | Fluffy | 0 | NULL || 3 | Wag | 0 | NULL || 1001 | Brian | 1 | NULL || 1002 | Rambo | 0 | NULL || 1003 | BamBam | 1 | NULL |+---------------------------+Vi har for nylig tilføjet
Dinner
kolonne, og den er stadigNULL
, venter på, at værdier bliver indsat.Men de værdier, der skal indsættes, afhænger af værdien af
GoodDog
kolonne.Vi kunne bruge en
CASE
udtryk i et sådant scenarie.OPDATERING Hunde SÆT Middag =CASE GoodDog NÅR 1 SÅ 'Sunday Roast' ELSE 'Airline food' ENDSELECT * FRA Hunde;
Resultat:
+-------------------------- --+| DogId | Hundenavn | GoodDog | Aftensmad ||--------+------------+------------------ -|| 1 | Hent | 1 | Søndagssteg || 2 | Fluffy | 0 | Flyselskab mad || 3 | Wag | 0 | Flyselskab mad || 1001 | Brian | 1 | Søndagssteg || 1002 | Rambo | 0 | Flyselskab mad || 1003 | BamBam | 1 | Søndagssteg |+---------+------------+------------------ --+CASE i en INSERT-erklæring
Vi kan tage tabellen fra ovenstående eksempel og indsætte en ny værdi.
Og vi kan igen drage fordel af
CASE
udtryk for at indsætte den passende værdi iDinner
kolonne.DECLARE @DogName nvarchar(60), @GoodDog bit;SET @DogName ='Doven';SET @GoodDog =0;INSERT INTO Hunde ( Hundenavn, GoodDog, Middag )VÆRDIER ( @DogName, @GoodDog, CASE @GoodDog NÅR 1 SÅ 'Sunday Roast' ELSE 'Airline food' END );SELECT * FROM Dogs;
Resultat:
+-------------------------- --+| DogId | Hundenavn | GoodDog | Aftensmad ||--------+------------+------------------ -|| 1 | Hent | 1 | Søndagssteg || 2 | Fluffy | 0 | Flyselskab mad || 3 | Wag | 0 | Flyselskab mad || 1001 | Brian | 1 | Søndagssteg || 1002 | Rambo | 0 | Flyselskab mad || 1003 | BamBam | 1 | Søndagssteg || 1004 | Dovne | 0 | Mad fra flyselskabet |+---------+-------+------------- --+Denne gang
CASE
udtryk evaluerede værdien af en variabel, vi lige havde indstillet, og derefter indsatte den passende værdi iDinner
kolonne.Er det en CASE-erklæring eller CASE-udtryk?
I SQL omtales mange ting som en "erklæring", når de faktisk er noget andet. Dette ser også ud til at være sandt for T-SQL "
CASE
erklæring”.Selvom det ofte omtales som
CASE
sætning, er det mere nøjagtigt at kalde detCASE
udtryk . Det er også sådan Microsoft-dokumentationen henviser til det.I SQL Server, i stedet for at være en sætning i sig selv,
CASE
kan bruges i enhver sætning eller klausul, der tillader et gyldigt udtryk. Et udtryk er en kombination af symboler og operatorer, der evalueres for at opnå en enkelt dataværdi.Nogle DBMS'er skelner dog mellem
CASE
sætning ogCASE
udtryk og har en lidt forskellig syntaks for hver. MySQL skelner mellemCASE
sætning ogCASE
operator, som i det væsentlige er den samme somCASE
udtryk.