sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server CASE-udtryk

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 stadig NULL , 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 i Dinner 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 i Dinner 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 det CASE 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 og CASE udtryk og har en lidt forskellig syntaks for hver. MySQL skelner mellem CASE sætning og CASE operator, som i det væsentlige er den samme som CASE udtryk.


  1. 4 måder at vælge duplikerede rækker i PostgreSQL

  2. Sådan omdøbes alle standardbegrænsninger i henhold til navnestandarder eller navngivningskonvention i SQL Server - SQL Server / TSQL vejledning del 93

  3. HikariCP Postgresql Driver hævder ikke at acceptere JDBC URL

  4. SQL, Hjælpetabel over tal