In SQL der CASE
-Anweisung wertet eine Liste von Bedingungen aus und gibt einen von mehreren möglichen Ergebnisausdrücken zurück.
In gewisser Weise ist das SQL CASE
-Anweisung ähnelt dem IF...ELSE
-Anweisung, da sie es uns ermöglicht, auf eine bestimmte Bedingung zu prüfen und je nach Ergebnis ein anderes Ergebnis zurückzugeben.
Ist es ein CASE
Anweisung oder CASE
Ausdruck?
In SQL werden Dinge manchmal als „Anweisung“ bezeichnet, obwohl sie eigentlich etwas anderes sind. Die SQL „CASE
Aussage“ ist ein typisches Beispiel (Entschuldigung für das Wortspiel!).
Der CASE
-Anweisung wird im SQL-Standard (ISO/IEC 9075) als CASE
bezeichnet Ausdruck . Sein Zweck besteht darin, „einen bedingten Wert anzugeben“.
Einige DBMSs unterscheiden jedoch zwischen dem CASE
-Anweisung und den CASE
Ausdruck und haben jeweils eine etwas andere Syntax. Beispielsweise stellen sowohl MySQL als auch MariaDB den CASE
bereit -Anweisung und den CASE
-Operator als zwei unterschiedliche Funktionen mit jeweils leicht unterschiedlicher Syntax.
CASE
Formate
In SQL gibt es zwei Formate von CASE
Ausdruck:
- Einfacher
CASE
Ausdruck - Suchte
CASE
Ausdruck
Nachfolgend finden Sie jeweils Beispiele.
Der einfache CASE
Ausdruck
Der einfache CASE
Ausdruck vergleicht einen Ausdruck mit einer Menge einfacher Ausdrücke, um das Ergebnis zu bestimmen.
Beispiel:
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;
Ergebnis:
Grass
Dieses Beispiel wurde in MySQL erstellt, aber der eigentliche CASE
Ausdruck sollte in den meisten großen RDBMSs funktionieren.
In diesem Beispiel mein CASE
Ausdruck ist Teil eines SELECT
Erklärung. Es prüft auf drei Bedingungen und hat ein ELSE
um für alles zu sorgen, was nicht in den drei Bedingungen abgedeckt ist.
In diesem Fall das Tier Cow
stimmt mit dem dritten WHEN
überein Ausdruck und den Ausdruck, der von seinem THEN
bereitgestellt wird zurückgegeben wird.
Um es klar zu sagen, der eigentliche CASE
Ausdruck ist dieser Teil:
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END
Welcher CASE
überprüft den Wert jedes WHEN
Ausdruck gegen den Eingabeausdruck. In diesem Beispiel der @animal
variable ist der Eingabeausdruck. Daher wird der Wert jedes WHEN
überprüft Ausdruck gegen @animal
Variable.
Wenn/falls es eine Übereinstimmung findet, gibt es den Ausdruck zurück, der durch das entsprechende THEN
bereitgestellt wird .
Mein Beispiel verwendet drei WHEN
Ausdrücke, aber je nach Anforderung hätte ich mehr und weniger verwenden können.
Der gesuchte CASE
Ausdruck
Der gesuchte CASE
expression wertet eine Reihe von booleschen Ausdrücken aus, um das Ergebnis zu bestimmen.
Hier ist ein Beispiel für einen gesuchten CASE
Ausdruck.
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;
Ergebnis:
Well done!
Der gesuchte CASE
expression hat keinen Eingabeausdruck wie der einfache CASE
Ausdruck.
Daran erinnern Sie sich in unserem einfachen CASE
Ausdruck, es begann mit CASE
@animal
, und daher wussten wir, dass der WHEN
Ausdrücke wurden alle gegen den Wert von @animal
ausgewertet .
Mit dem gesuchten CASE
Ausdruck, wir geben am Anfang keinen Eingabeausdruck wie diesen. Stattdessen jedes WHEN
Ausdruck enthält einen booleschen Ausdruck, für den ausgewertet werden soll.
Ein Datenbankbeispiel
Hier ist ein Beispiel, das zeigt, wie der CASE
Ausdruck kann innerhalb einer Datenbankabfrage verwendet werden.
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;
Ergebnis:
+---------------+------------+------------+ | 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 | +---------------+------------+------------+
Dieses Beispiel verwendet einen gesuchten CASE
Ausdruck, um die Ergebnisse der Population
auszuwerten Spalte City
Tisch.
ELSE
ist optional
Das ELSE
Argument ist optional. Wenn wir das ELSE
weglassen , und keine der Bedingungen ausgelöst wird, ist das Ergebnis NULL
.
Folgendes passiert, wenn wir ELSE
weglassen Klausel aus dem vorherigen Beispiel:
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;
Ergebnis:
+---------------+------------+-----------+ | 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 einem UPDATE
Erklärung
Lassen Sie uns eine Spalte zu City
hinzufügen Tabelle aus dem vorherigen Beispiel:
ALTER TABLE City
ADD COLUMN Size VARCHAR(30) AFTER Population;
SELECT * FROM City
LIMIT 10;
So sieht es jetzt aus:
+----+----------------+-------------+---------------+------------+------+ | 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 | +----+----------------+-------------+---------------+------------+------+
Wir haben keine Daten in die neue Size
eingefügt Spalte, also gibt es NULL
zurück in jeder Zeile.
Wir können jetzt einen CASE
verwenden Ausdruck, um die Size
zu aktualisieren Spalte mit einem Wert, der vom Wert in Population
abhängt Spalte:
UPDATE City
SET Size =
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END;
Lassen Sie uns nun Daten aus der Tabelle auswählen:
SELECT * FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Ergebnis:
+------+---------------+-------------+---------------+------------+------------+ | 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 einem INSERT
Erklärung
Angenommen, wir haben die folgende Tabelle in einer SQL Server-Datenbank:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
Lassen Sie uns eine neue Zeile in diese Tabelle einfügen. Aber verwenden wir den CASE
Ausdruck, um den entsprechenden Wert in Dinner
einzufügen Spalte, abhängig vom Wert in GoodDog
Spalte:
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 der CASE
Der Ausdruck hat den Wert einer Variablen ausgewertet, die wir gerade gesetzt hatten, und dann den entsprechenden Wert in Dinner
eingefügt Spalte.
Sehen wir uns nun die Tabelle noch einmal an:
SELECT * FROM Dogs;
Ergebnis:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
Wir können sehen, dass der entsprechende Wert im Dinner
steht Spalte.
CASE
in einem ORDER BY
Klausel
Der CASE
Ausdruck kann in jeder Anweisung oder Klausel verwendet werden, die einen gültigen Ausdruck zulässt. Daher können Sie es in Anweisungen wie SELECT
verwenden , UPDATE
, DELETE
und SET
, und in Klauseln wie IN
, WHERE
, ORDER BY
, GROUP BY
, und HAVING
.
Verwenden eines CASE
Ausdruck im ORDER BY
einer Anweisung -Klausel kann praktisch sein, wenn Sie beim Sortieren Ihrer Ergebnisse eine Ausnahme für bestimmte Werte machen möchten.
Angenommen, wir führen die folgende Abfrage für eine Tabelle aus, die Musikgenres enthält.
SELECT Genre
FROM Genres
ORDER BY Genre ASC;
Ergebnis:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Other | | Pop | | Punk | | Rap | | Rock | +---------+
Hier ordnen wir die Ergebnisse nach Genre
Spalte, in aufsteigender Reihenfolge.
Das ist in Ordnung, bis auf eine Sache. Das Genre namens Other
. Wäre es nicht schön, wenn wir Other
verschieben könnten nach unten?
Dies erreichen wir mit dem CASE
Ausdruck, indem Sie die obige Abfrage nehmen und wie folgt ändern.
SELECT Genre
FROM Genres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Ergebnis:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Pop | | Punk | | Rap | | Rock | | Other | +---------+
Das COALESCE()
und NULLIF()
Funktionen
Je nach Szenario können wir Funktionen wie COALESCE()
verwenden und NULLIF()
als Abkürzung, anstatt den CASE
zu verwenden Ausdruck.
Diese beiden Funktionen sind SQL-Standard und funktionieren wie folgt:
NULLIF (V1, V2)
Entspricht:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
Und:
COALESCE (V1, V2)
Entspricht:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
Auch:
COALESCE (V1, V2, ..., Vn)
Entspricht:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2, ..., Vn) END