In vielen Situationen möchten wir Daten basierend auf bestimmten Bedingungen transformieren oder auswerten. SQL bietet dafür den CASE-Ausdruck, der es uns ermöglicht, unterschiedliche Werte zurückzugeben, je nachdem, ob eine Bedingung erfüllt ist oder nicht.
CASE-Ausdrücke erlauben es uns, Bedingungen zu prüfen und basierend auf den Ergebnissen unterschiedliche Werte zurückzugeben. Dies ist besonders nützlich für:
-- Einfaches Beispiel: Status in lesbare Form bringen
SELECT
bestellnummer,
status,
CASE status
WHEN 'N' THEN 'Neu'
WHEN 'B' THEN 'Bearbeitung'
WHEN 'V' THEN 'Versendet'
ELSE 'Unbekannt'
END AS status_text
FROM bestellungen;
-- Beispiel: Kategorisierung von Zahlen
SELECT
produkt_id,
lagerbestand,
CASE
WHEN lagerbestand = 0 THEN 'Nicht verfügbar'
WHEN lagerbestand < 10 THEN 'Fast ausverkauft'
WHEN lagerbestand < 50 THEN 'Verfügbar'
ELSE 'Gut verfügbar'
END AS verfuegbarkeit
FROM produkte;Im ersten Beispiel wird der Bestellstatus, der in der Tabelle als
einzelner Buchstabe gespeichert ist, in einen lesbaren Text umgewandelt.
Der CASE-Ausdruck prüft den Wert des status und gibt den
entsprechenden Text zurück.
Das zweite Beispiel zeigt, wie man Zahlen in Kategorien einteilen kann. Hier wird der Lagerbestand eines Produkts geprüft und je nach Menge eine entsprechende Verfügbarkeitsbeschreibung zurückgegeben.
Der einfache CASE-Ausdruck vergleicht einen Ausdruck mit einer Reihe von möglichen Werten. Die Syntax sieht folgendermaßen aus:
-- Grundstruktur
CASE ausdruck
WHEN wert1 THEN ergebnis1
WHEN wert2 THEN ergebnis2
[ELSE ergebnis3]
ENDDer ausdruck wird nacheinander mit den angegebenen
Werten verglichen. Wenn eine Übereinstimmung gefunden wird, wird das
entsprechende Ergebnis zurückgegeben. Wenn keine Übereinstimmung
gefunden wird und ein ELSE-Zweig angegeben ist, wird dessen
Ergebnis zurückgegeben. Ohne ELSE wird NULL
zurückgegeben.
-- Praktisches Beispiel: Monatsnamen
SELECT
bestelldatum,
CASE MONTH(bestelldatum)
WHEN 1 THEN 'Januar'
WHEN 2 THEN 'Februar'
WHEN 3 THEN 'März'
-- ... weitere Monate
WHEN 12 THEN 'Dezember'
ELSE 'Ungültig'
END AS monatsname
FROM bestellungen;
-- Beispiel: Bewertungen umwandeln
SELECT
produkt_id,
bewertung,
CASE bewertung
WHEN 1 THEN '★☆☆☆☆'
WHEN 2 THEN '★★☆☆☆'
WHEN 3 THEN '★★★☆☆'
WHEN 4 THEN '★★★★☆'
WHEN 5 THEN '★★★★★'
ELSE 'Keine Bewertung'
END AS bewertung_sterne
FROM produktbewertungen;Im ersten Beispiel wird aus dem Bestelldatum der Monatsname
ermittelt. Dazu wird mit der MONTH-Funktion die
Monatsnummer extrahiert und im CASE-Ausdruck mit den möglichen Werten
verglichen.
Das zweite Beispiel zeigt, wie man numerische Bewertungen in eine visuelle Darstellung mit Sternen umwandeln kann. Der CASE-Ausdruck ordnet jeder Bewertungszahl die entsprechende Anzahl von Sternen zu.
Der Searched CASE ermöglicht es, komplexere Bedingungen zu formulieren. Anstatt einen Ausdruck mit Werten zu vergleichen, können hier beliebige Bedingungen geprüft werden. Die Syntax sieht folgendermaßen aus:
-- Grundstruktur
CASE
WHEN bedingung1 THEN ergebnis1
WHEN bedingung2 THEN ergebnis2
[ELSE ergebnis3]
ENDDie Bedingungen werden in der angegebenen Reihenfolge geprüft. Die
erste Bedingung, die zutrifft, bestimmt das zurückgegebene Ergebnis.
Wenn keine Bedingung zutrifft und ein ELSE-Zweig angegeben
ist, wird dessen Ergebnis zurückgegeben. Ohne ELSE wird
NULL zurückgegeben.
-- Beispiel: Gehaltsklassen
SELECT
name,
gehalt,
CASE
WHEN gehalt < 30000 THEN 'Niedrig'
WHEN gehalt < 50000 THEN 'Mittel'
WHEN gehalt < 80000 THEN 'Hoch'
ELSE 'Sehr hoch'
END AS gehaltsklasse
FROM mitarbeiter;
-- Beispiel: Altersgruppen mit überlappenden Bedingungen
SELECT
name,
geburtsdatum,
CASE
WHEN alter < 18 THEN 'Minderjährig'
WHEN alter BETWEEN 18 AND 25 THEN 'Junge Erwachsene'
WHEN alter BETWEEN 26 AND 65 THEN 'Erwachsene'
WHEN alter > 65 THEN 'Senioren'
ELSE 'Unbekannt'
END AS altersgruppe
FROM kunden;
-- Beispiel: Komplexe Bedingungen
SELECT
bestellnummer,
betrag,
lieferstatus,
zahlungsstatus,
CASE
WHEN lieferstatus = 'geliefert'
AND zahlungsstatus = 'bezahlt'
THEN 'Abgeschlossen'
WHEN lieferstatus = 'geliefert'
AND zahlungsstatus = 'offen'
THEN 'Zahlung ausstehend'
WHEN lieferstatus IN ('neu', 'in Bearbeitung')
AND zahlungsstatus = 'bezahlt'
THEN 'Lieferung ausstehend'
ELSE 'In Bearbeitung'
END AS bestellstatus
FROM bestellungen;Im ersten Beispiel werden Mitarbeiter anhand ihres Gehalts in verschiedene Gehaltsklassen eingeteilt. Die Bedingungen prüfen das Gehalt und geben die entsprechende Klasse zurück.
Das zweite Beispiel zeigt, wie man überlappende Bedingungen formulieren kann. Hier werden Kunden anhand ihres Alters in verschiedene Altersgruppen eingeteilt. Die Bedingungen sind so formuliert, dass jeder Kunde genau einer Gruppe zugeordnet wird.
Im dritten Beispiel werden komplexe Bedingungen verwendet, um den
Status einer Bestellung zu ermitteln. Hier werden mehrere Spalten
(lieferstatus und zahlungsstatus) in den
Bedingungen kombiniert, um den entsprechenden Bestellstatus zu
bestimmen.
Praktische Anwendungsbeispiele zeigen, wie CASE-Ausdrücke in verschiedenen Situationen eingesetzt werden können:
SELECT
produkt_id,
preis,
CASE
WHEN kategorie = 'Premium' THEN preis * 0.9
WHEN kategorie = 'Standard' THEN preis * 0.95
ELSE preis
END AS rabattierter_preis
FROM produkte;Hier wird der Preis eines Produkts basierend auf seiner Kategorie rabattiert. Für Produkte der Kategorie ‘Premium’ wird ein Rabatt von 10% gewährt, für ‘Standard’-Produkte 5%. Alle anderen Produkte bleiben unverändert.
SELECT
name,
CASE
WHEN telefon IS NULL AND mobil IS NOT NULL
THEN CONCAT('Mobil: ', mobil)
WHEN telefon IS NOT NULL AND mobil IS NULL
THEN CONCAT('Tel: ', telefon)
WHEN telefon IS NOT NULL AND mobil IS NOT NULL
THEN CONCAT('Tel: ', telefon, ', Mobil: ', mobil)
ELSE 'Keine Nummer'
END AS kontakt
FROM kunden;In diesem Beispiel wird die Kontaktinformation eines Kunden formatiert. Je nachdem, ob Telefon- und/oder Mobilnummer vorhanden sind, wird eine entsprechende Ausgabe generiert.
SELECT
CASE
WHEN land IN ('DE', 'AT', 'CH') THEN 'DACH'
WHEN land IN ('FR', 'IT', 'ES') THEN 'Südeuropa'
ELSE 'Andere'
END AS region,
COUNT(*) as anzahl,
AVG(umsatz) as durchschnittsumsatz
FROM kunden
GROUP BY
CASE
WHEN land IN ('DE', 'AT', 'CH') THEN 'DACH'
WHEN land IN ('FR', 'IT', 'ES') THEN 'Südeuropa'
ELSE 'Andere'
END;Hier werden Kunden anhand ihres Landes in Regionen eingeteilt. Für jede Region werden dann die Anzahl der Kunden und der durchschnittliche Umsatz berechnet. Der CASE-Ausdruck wird sowohl in der SELECT-Liste als auch in der GROUP BY-Klausel verwendet, um die Gruppierung nach den definierten Regionen durchzuführen.
UPDATE produkte
SET rabatt =
CASE
WHEN lagerbestand > 100 THEN 20
WHEN lagerbestand > 50 THEN 10
WHEN lagerbestand > 20 THEN 5
ELSE 0
END;Dieses Beispiel zeigt, wie man mit einem CASE-Ausdruck Werte in einer Tabelle aktualisieren kann. Hier wird der Rabatt für Produkte basierend auf ihrem Lagerbestand festgelegt. Produkte mit hohem Lagerbestand erhalten einen höheren Rabatt als Produkte mit niedrigem Bestand.
Tipps zur Optimierung und Behandlung von NULL-Werten runden das Thema ab:
-- Index für häufig verwendete Bedingungen
CREATE INDEX idx_status_betrag
ON bestellungen(status, betrag);
-- Komplexe CASE-Ausdrücke in View auslagern
CREATE VIEW bestellstatus AS
SELECT
bestellnummer,
CASE
WHEN status = 'N' AND betrag > 1000 THEN 'Wichtig'
WHEN status = 'N' THEN 'Normal'
ELSE 'Abgeschlossen'
END AS prioritaet
FROM bestellungen;Um die Performanz von Abfragen mit CASE-Ausdrücken zu verbessern, können Indizes für häufig verwendete Bedingungen erstellt werden. Dadurch kann die Datenbank die relevanten Datensätze schneller finden.
Eine weitere Möglichkeit ist es, komplexe CASE-Ausdrücke in eine Sicht (View) auszulagern. Dadurch muss der Ausdruck nicht bei jeder Abfrage neu ausgewertet werden, sondern kann einfach über die Sicht abgefragt werden.
-- NULL-Werte explizit behandeln
SELECT
name,
CASE
WHEN email IS NULL THEN 'Keine E-Mail'
ELSE email
END AS kontakt
FROM kunden;Bei der Arbeit mit CASE-Ausdrücken ist es wichtig, NULL-Werte zu berücksichtigen. In diesem Beispiel wird geprüft, ob die E-Mail-Adresse eines Kunden NULL ist. Wenn ja, wird stattdessen der Text ‘Keine E-Mail’ zurückgegeben.
-- Kommentare für komplexe Bedingungen
SELECT
auftragsnummer,
CASE
-- Eilaufträge
WHEN prioritaet = 1 AND lieferzeit < 24 THEN 'Express'
-- Standardaufträge
WHEN prioritaet = 2 THEN 'Standard'
-- Alle anderen
ELSE 'Normal'
END AS auftragstyp
FROM auftraege;Gerade bei komplexen Bedingungen kann es hilfreich sein, Kommentare im SQL-Code zu verwenden. Dadurch wird die Logik des CASE-Ausdrucks klarer und der Code ist leichter zu warten.
CASE-Ausdrücke sind ein mächtiges Werkzeug, um Daten basierend auf Bedingungen zu transformieren und auszuwerten. Sie ermöglichen es, SQL-Abfragen flexibler und aussagekräftiger zu gestalten und die Ergebnisse an spezifische Anforderungen anzupassen.
Bei der Verwendung von CASE-Ausdrücken sollte man jedoch auch die Performanz im Auge behalten. Komplexe Bedingungen können die Ausführungszeit einer Abfrage erhöhen. Durch den gezielten Einsatz von Indizes und das Auslagern komplexer Ausdrücke in Sichten kann man die Performanz oft verbessern.
Auch die Behandlung von NULL-Werten ist ein wichtiger Aspekt bei der Arbeit mit CASE-Ausdrücken. Durch die explizite Prüfung auf NULL-Werte kann man sicherstellen,