In SQL is de CASE
statement evalueert een lijst met voorwaarden en retourneert een van meerdere mogelijke resultaatuitdrukkingen.
In sommige opzichten is de SQL CASE
statement lijkt een beetje op de IF...ELSE
verklaring in dat het ons in staat stelt om te controleren op een bepaalde voorwaarde en een ander resultaat te retourneren, afhankelijk van de uitkomst.
Is het een CASE
Verklaring of CASE
Uitdrukking?
In SQL worden dingen soms een "statement" genoemd, terwijl ze in feite iets anders zijn. De SQL “CASE
statement” is een goed voorbeeld (sorry voor de woordspeling!).
De CASE
statement wordt in de SQL-standaard (ISO/IEC 9075) aangeduid als de CASE
uitdrukking . Het doel is om "een voorwaardelijke waarde op te geven".
Sommige DBMS'en maken echter onderscheid tussen de CASE
statement en de CASE
expressie, en hebben voor elk een iets andere syntaxis. Zowel MySQL als MariaDB bieden bijvoorbeeld de CASE
statement en de CASE
operator als twee verschillende functies, elk met een iets andere syntaxis.
CASE
Formaten
In SQL zijn er twee formaten van CASE
uitdrukking:
- Eenvoudige
CASE
uitdrukking - Gezocht
CASE
uitdrukking
Hieronder staan voorbeelden van elk.
De eenvoudige CASE
Uitdrukking
De eenvoudige CASE
uitdrukking vergelijkt een uitdrukking met een reeks eenvoudige uitdrukkingen om het resultaat te bepalen.
Voorbeeld:
DECLARE @animal VARCHAR(40);
SET @animal = 'Cow';
SELECT
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END;
Resultaat:
Grass
Dit voorbeeld is gemaakt in MySQL, maar de eigenlijke CASE
expressie zou in de meeste grote RDBMS'en moeten werken.
In dit voorbeeld is mijn CASE
expressie maakt deel uit van een SELECT
uitspraak. Het controleert op drie voorwaarden en heeft een ELSE
om te voorzien in alles wat niet onder de drie voorwaarden valt.
In dit geval het dier Cow
komt overeen met de derde WHEN
expressie, en de expressie geleverd door zijn THEN
wordt geretourneerd.
Voor alle duidelijkheid:de eigenlijke CASE
uitdrukking is dit deel:
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END
Wat CASE
doet is de waarde van elke WHEN
. controleren expressie tegen de invoerexpressie. In dit voorbeeld is de @animal
variabele is de invoerexpressie. Daarom controleert het de waarde van elke WHEN
uitdrukking tegen de @animal
variabel.
Wanneer/als het een overeenkomst vindt, retourneert het de uitdrukking die wordt geleverd door de corresponderende THEN
.
Mijn voorbeeld gebruikt drie WHEN
uitdrukkingen, maar ik had meer en minder kunnen gebruiken, afhankelijk van de vereisten.
De gezochte CASE
Uitdrukking
De gezochte CASE
expression evalueert een set Booleaanse expressies om het resultaat te bepalen.
Hier is een voorbeeld van een gezochte CASE
uitdrukking.
DECLARE @score int;
SET @score = 7;
SELECT
CASE
WHEN @score > 8 THEN 'Congratulations!'
WHEN @score > 5 AND @score < 8 THEN 'Well done!'
ELSE 'Try harder next time'
END;
Resultaat:
Well done!
De gezochte CASE
expressie heeft geen invoerexpressie zoals de eenvoudige CASE
uitdrukking.
U herinnert zich dat in onze eenvoudige CASE
uitdrukking, het begon met CASE
@animal
, en daarom wisten we dat de WHEN
expressies evalueerden allemaal tegen de waarde van @animal
.
Met de gezochte CASE
expressie, bieden we aan het begin geen invoerexpressie op die manier. In plaats daarvan wordt elke WHEN
expressie bevat een Booleaanse expressie waarvoor geëvalueerd moet worden.
Een databasevoorbeeld
Hier is een voorbeeld dat laat zien hoe de CASE
expressie kan worden gebruikt binnen een databasequery.
USE World;
SELECT
Name,
Population,
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Resultaat:
+---------------+------------+------------+ | Name | Population | Size | +---------------+------------+------------+ | New York | 8008278 | Huge City | | Los Angeles | 3694820 | Huge City | | Chicago | 2896016 | Huge City | | Houston | 1953631 | Big City | | Philadelphia | 1517550 | Big City | | Phoenix | 1321045 | Big City | | San Diego | 1223400 | Big City | | Dallas | 1188580 | Big City | | San Antonio | 1144646 | Big City | | Detroit | 951270 | Small City | | San Jose | 894943 | Small City | | Indianapolis | 791926 | Small City | | San Francisco | 776733 | Small City | | Jacksonville | 735167 | Small City | | Columbus | 711470 | Small City | | Austin | 656562 | Small City | | Baltimore | 651154 | Small City | | Memphis | 650100 | Small City | | Milwaukee | 596974 | Small City | | Boston | 589141 | Small City | +---------------+------------+------------+
Dit voorbeeld gebruikt een gezochte CASE
expressie om de resultaten van de Population
. te evalueren kolom van de City
tafel.
ELSE
is optioneel
De ELSE
argument is optioneel. Als we de ELSE
. weglaten , en geen van de voorwaarden wordt geactiveerd, is het resultaat NULL
.
Dit is wat er gebeurt als we de ELSE
weglaten clausule uit het vorige voorbeeld:
USE World;
SELECT
Name,
Population,
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Resultaat:
+---------------+------------+-----------+ | Name | Population | Size | +---------------+------------+-----------+ | New York | 8008278 | Huge City | | Los Angeles | 3694820 | Huge City | | Chicago | 2896016 | Huge City | | Houston | 1953631 | Big City | | Philadelphia | 1517550 | Big City | | Phoenix | 1321045 | Big City | | San Diego | 1223400 | Big City | | Dallas | 1188580 | Big City | | San Antonio | 1144646 | Big City | | Detroit | 951270 | NULL | | San Jose | 894943 | NULL | | Indianapolis | 791926 | NULL | | San Francisco | 776733 | NULL | | Jacksonville | 735167 | NULL | | Columbus | 711470 | NULL | | Austin | 656562 | NULL | | Baltimore | 651154 | NULL | | Memphis | 650100 | NULL | | Milwaukee | 596974 | NULL | | Boston | 589141 | NULL | +---------------+------------+-----------+
CASE
in een UPDATE
Verklaring
Laten we een kolom toevoegen aan de City
tabel uit het vorige voorbeeld:
ALTER TABLE City
ADD COLUMN Size VARCHAR(30) AFTER Population;
SELECT * FROM City
LIMIT 10;
Zo ziet het er nu uit:
+----+----------------+-------------+---------------+------------+------+ | ID | Name | CountryCode | District | Population | Size | +----+----------------+-------------+---------------+------------+------+ | 1 | Kabul | AFG | Kabol | 1780000 | NULL | | 2 | Qandahar | AFG | Qandahar | 237500 | NULL | | 3 | Herat | AFG | Herat | 186800 | NULL | | 4 | Mazar-e-Sharif | AFG | Balkh | 127800 | NULL | | 5 | Amsterdam | NLD | Noord-Holland | 731200 | NULL | | 6 | Rotterdam | NLD | Zuid-Holland | 593321 | NULL | | 7 | Haag | NLD | Zuid-Holland | 440900 | NULL | | 8 | Utrecht | NLD | Utrecht | 234323 | NULL | | 9 | Eindhoven | NLD | Noord-Brabant | 201843 | NULL | | 10 | Tilburg | NLD | Noord-Brabant | 193238 | NULL | +----+----------------+-------------+---------------+------------+------+
We hebben geen gegevens ingevoegd in de nieuwe Size
kolom, dus het retourneert NULL
in elke rij.
We kunnen nu een CASE
. gebruiken expressie om de Size
. bij te werken kolom met een waarde die afhangt van de waarde in de Population
kolom:
UPDATE City
SET Size =
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END;
Laten we nu gegevens uit de tabel selecteren:
SELECT * FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Resultaat:
+------+---------------+-------------+---------------+------------+------------+ | ID | Name | CountryCode | District | Population | Size | +------+---------------+-------------+---------------+------------+------------+ | 3793 | New York | USA | New York | 8008278 | Huge City | | 3794 | Los Angeles | USA | California | 3694820 | Huge City | | 3795 | Chicago | USA | Illinois | 2896016 | Huge City | | 3796 | Houston | USA | Texas | 1953631 | Big City | | 3797 | Philadelphia | USA | Pennsylvania | 1517550 | Big City | | 3798 | Phoenix | USA | Arizona | 1321045 | Big City | | 3799 | San Diego | USA | California | 1223400 | Big City | | 3800 | Dallas | USA | Texas | 1188580 | Big City | | 3801 | San Antonio | USA | Texas | 1144646 | Big City | | 3802 | Detroit | USA | Michigan | 951270 | Small City | | 3803 | San Jose | USA | California | 894943 | Small City | | 3804 | Indianapolis | USA | Indiana | 791926 | Small City | | 3805 | San Francisco | USA | California | 776733 | Small City | | 3806 | Jacksonville | USA | Florida | 735167 | Small City | | 3807 | Columbus | USA | Ohio | 711470 | Small City | | 3808 | Austin | USA | Texas | 656562 | Small City | | 3809 | Baltimore | USA | Maryland | 651154 | Small City | | 3810 | Memphis | USA | Tennessee | 650100 | Small City | | 3811 | Milwaukee | USA | Wisconsin | 596974 | Small City | | 3812 | Boston | USA | Massachusetts | 589141 | Small City | +------+---------------+-------------+---------------+------------+------------+
CASE
in een INSERT
Verklaring
Stel dat we de volgende tabel in een SQL Server-database hebben:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
Laten we een nieuwe rij in die tabel invoegen. Maar laten we de CASE
. gebruiken expressie om de juiste waarde in te voegen in het Dinner
kolom, afhankelijk van de waarde in de GoodDog
kolom:
DECLARE @DogName nvarchar(60), @GoodDog bit;
SET @DogName = 'Lazy';
SET @GoodDog = 0;
INSERT INTO Dogs ( DogName, GoodDog, Dinner )
VALUES (
@DogName,
@GoodDog,
CASE @GoodDog
WHEN 1 THEN 'Sunday Roast'
ELSE 'Airline food'
END
);
Hier, de CASE
expression evalueerde de waarde van een variabele die we zojuist hadden ingesteld en voegde vervolgens de juiste waarde toe aan het Dinner
kolom.
Laten we nu de tabel opnieuw bekijken:
SELECT * FROM Dogs;
Resultaat:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
We kunnen zien dat de juiste waarde in het Dinner
. staat kolom.
CASE
in een ORDER BY
Clausule
De CASE
expressie kan worden gebruikt in elke instructie of clausule die een geldige expressie toestaat. Daarom kunt u het gebruiken in instructies zoals SELECT
, UPDATE
, DELETE
en SET
, en in clausules zoals IN
, WHERE
, ORDER BY
, GROUP BY
, en HAVING
.
Een CASE
gebruiken uitdrukking in de ORDER BY
. van een instructie clausule kan handig zijn wanneer u een speciale uitzondering wilt maken voor bepaalde waarden bij het bestellen van uw resultaten.
Stel dat we de volgende query uitvoeren op een tabel met muziekgenres.
SELECT Genre
FROM Genres
ORDER BY Genre ASC;
Resultaat:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Other | | Pop | | Punk | | Rap | | Rock | +---------+
Hier rangschikken we de resultaten op Genre
kolom, in oplopende volgorde.
Dit is prima, op één ding na. Het genre genaamd Other
. Zou het niet mooi zijn als we Other
. konden verplaatsen naar beneden?
We kunnen dit bereiken met de CASE
expressie door de bovenstaande query te nemen en deze als volgt aan te passen.
SELECT Genre
FROM Genres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Resultaat:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Pop | | Punk | | Rap | | Rock | | Other | +---------+
De COALESCE()
en NULLIF()
Functies
Afhankelijk van het scenario kunnen we functies gebruiken zoals COALESCE()
en NULLIF()
als een snelkoppeling, in plaats van de CASE
uitdrukking.
Deze twee functies zijn standaard SQL en werken als volgt:
NULLIF (V1, V2)
Is gelijk aan:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
En:
COALESCE (V1, V2)
Is gelijk aan:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
Ook:
COALESCE (V1, V2, ..., Vn)
Is gelijk aan:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2, ..., Vn) END