Premium

Bedingte Logik, der CASE-Ausdruck

SQL erlaubt es dir – wie viele Programmiersprachen – bedingte Logik zu schreiben, sodass je nach einer Reihe von Bedingungen einer von mehreren möglichen Werten zurückgegeben wird. In diesem Artikel sehen wir uns an, wie das in SQL mit dem CASE-Ausdruck funktioniert.

Was ist bedingte Logik?

Unter bedingter Logik versteht man, dass ein Programm je nach bestimmten Bedingungen mehrere Ausführungspfade hat.

Beispiel: In der Datenbank „Schedule" gibt es die Tabelle Student mit dem Feld birthday, das das Geburtsdatum eines Studenten enthält. Angenommen, in der Ergebnismenge soll nicht das Geburtsdatum selbst stehen, sondern der Text „Volljährig" oder „Minderjährig" – je nachdem, ob der Student schon 18 ist. Das ist bedingte Logik: Je nach konkreter Bedingung wird entweder der eine oder der andere Wert ausgegeben.

So eine Query mit CASE kann zum Beispiel so aussehen:

MySQL 8.1
SELECT first_name, last_name,
CASE
  WHEN TIMESTAMPDIFF(YEAR, birthday, NOW()) >= 18 THEN 'Volljährig'
  ELSE 'Minderjährig'
END AS status
FROM Student
MySQL 8.1
SELECT first_name, last_name,
CASE
  WHEN EXTRACT(YEAR FROM AGE(NOW(), birthday)) >= 18 THEN 'Volljährig'
  ELSE 'Minderjährig'
END AS status
FROM Student
first_namelast_namestatus
NikolajSokolovVolljährig
VyacheslavEliseevVolljährig
IvanEfremovVolljährig
AnatolijZHdanovMinderjährig
GeorgijNoskovVolljährig
ArtyomSergeevMinderjährig
ArinaEvseevaVolljährig
AngelinaVoroncovaVolljährig
EkaterinaUstinovaVolljährig
RaisaLapinaVolljährig
LeonidIgnatovMinderjährig
SnezhanaSeliverstovaVolljährig
SemyonBiryukovVolljährig
GeorgijBaranovVolljährig
YUliyaVishnyakovaVolljährig
ValentinaBolshakovaVolljährig
LeonidKryukovVolljährig
VladislavCvetkovVolljährig
SnezhanaMorozovaVolljährig
LyubovBorisovaVolljährig
AnfisaKalashnikovaVolljährig
AnnaOsipovaVolljährig

Syntax des suchenden CASE-Ausdrucks

MySQL 8.1
CASE
    WHEN bedingung_1 THEN rueckgabe_wert_1
    WHEN bedingung_2 THEN rueckgabe_wert_2
    WHEN bedingung_n THEN rueckgabe_wert_n
    [ELSE standard_rueckgabe_wert]
END

Wenn bedingung_1 wahr ist, gibt der CASE-Ausdruck rueckgabe_wert_1 zurück, andernfalls wird bedingung_2 geprüft und so weiter. Trifft keine der Bedingungen zu, kommt NULL zurück – oder standard_rueckgabe_wert, falls ein ELSE-Zweig angegeben ist.

Beispiel

Schauen wir uns CASE am Beispiel der Bestimmung der Schulstufe an.

Stufen der Schulbildung

MySQL 8.1
SELECT name,
CASE
  WHEN SUBSTRING(name, 1, INSTR(name, ' ')) IN (10, 11) THEN 'Oberstufe'
  WHEN SUBSTRING(name, 1, INSTR(name, ' ')) IN (5, 6, 7, 8, 9) THEN 'Mittelstufe'
  ELSE 'Grundschule'
END AS stage
FROM Class
MySQL 8.1
SELECT name,
CASE
  WHEN SUBSTRING(name, 1, POSITION(' ' IN name) - 1) IN ('10', '11') THEN 'Oberstufe'
  WHEN SUBSTRING(name, 1, POSITION(' ' IN name) - 1) IN ('5', '6', '7', '8', '9') THEN 'Mittelstufe'
  ELSE 'Grundschule'
END AS stage
FROM Class
namestage
8 AMittelstufe
8 BMittelstufe
9 CMittelstufe
9 BMittelstufe
9 AMittelstufe
10 BOberstufe
10 AOberstufe
11 BOberstufe
11 AOberstufe
7 AMittelstufe
7 BMittelstufe
6 AMittelstufe
6 BMittelstufe
5 AMittelstufe
5 BMittelstufe
4 AGrundschule
  • Zuerst extrahieren wir die Klassennummer aus dem Namen:
    MySQL 8.1
    SUBSTRING(name, 1, INSTR(name, ' '))
    
  • Zuerst extrahieren wir die Klassennummer aus dem Namen:
    MySQL 8.1
    SUBSTRING(name, 1, POSITION(' ' IN name) - 1)
    
  • Dann prüfen wir, ob diese Nummer zur Liste der Oberstufen- bzw. Mittelstufenklassen gehört.
  • Liegt die Klassennummer nicht im Bereich 5–11, geben wir „Grundschule" aus.

Syntax des einfachen CASE-Ausdrucks

CASE hat auch eine einfachere Syntax, die dem suchenden CASE ähnelt, aber weniger flexibel ist. Allgemein sieht sie so aus:

MySQL 8.1
CASE wert
    WHEN vergleichs_wert_1 THEN rueckgabe_wert_1
    WHEN vergleichs_wert_2 THEN rueckgabe_wert_2
    WHEN vergleichs_wert_n THEN rueckgabe_wert_n
    [ELSE standard_rueckgabe_wert]
END

Bei dieser Syntax wird wert in CASE nacheinander mit den in WHEN angegebenen Werten verglichen. Stimmt einer überein, wird der Wert nach THEN zurückgegeben.

Mit dieser Syntax können wir unser vorheriges Beispiel so umschreiben:

MySQL 8.1
SELECT name,
CASE SUBSTRING(name, 1, INSTR(name, ' '))
  WHEN 11 THEN 'Oberstufe'
  WHEN 10 THEN 'Oberstufe'
  WHEN 9 THEN 'Mittelstufe'
  WHEN 8 THEN 'Mittelstufe'
  WHEN 7 THEN 'Mittelstufe'
  WHEN 6 THEN 'Mittelstufe'
  WHEN 5 THEN 'Mittelstufe'
  ELSE 'Grundschule'
END AS stage
FROM Class
MySQL 8.1
SELECT name,
CASE SUBSTRING(name, 1, POSITION(' ' IN name) - 1)
  WHEN '11' THEN 'Oberstufe'
  WHEN '10' THEN 'Oberstufe'
  WHEN '9' THEN 'Mittelstufe'
  WHEN '8' THEN 'Mittelstufe'
  WHEN '7' THEN 'Mittelstufe'
  WHEN '6' THEN 'Mittelstufe'
  WHEN '5' THEN 'Mittelstufe'
  ELSE 'Grundschule'
END AS stage
FROM Class
namestage
8 AMittelstufe
8 BMittelstufe
9 CMittelstufe
9 BMittelstufe
9 AMittelstufe
10 BOberstufe
10 AOberstufe
11 BOberstufe
11 AOberstufe
7 AMittelstufe
7 BMittelstufe
6 AMittelstufe
6 BMittelstufe
5 AMittelstufe
5 BMittelstufe
4 AGrundschule

Prüf dich selbst

Welchen Wert gibt der CASE-Ausdruck in diesem Fall zurück?

MySQL 8.1
CASE 2
  WHEN 0 THEN 'Null'
  WHEN 1 THEN 'Eins'
  ELSE 'Viele'
END