Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQL CASE-Anweisung

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