CASE bringt Wenn/Dann/Sonst-Logik in eine SQL-Abfrage: Es prüft eine Liste von Bedingungen und gibt das Ergebnis der ersten zurück, die zutrifft. Die Beispiele funktionieren in PostgreSQL, MySQL, SQLite und SQL Server.
So verwendest du CASE
Schreib WHEN condition THEN result-Paare zwischen CASE und END. CASE gibt das Ergebnis der ersten zutreffenden Bedingung zurück oder den ELSE-Wert, wenn keine zutrifft:
CASE
WHEN condition THEN result
[WHEN condition THEN result ...]
[ELSE result]
END
SELECT
CASE
WHEN 72 >= 90 THEN 'Hot'
WHEN 72 >= 60 THEN 'Mild'
ELSE 'Cold'
END;
-- Output: Mild
Wenn jede Bedingung denselben Wert auf Gleichheit prüft, nennt die kürzere „einfache“ Form diesen Wert nur einmal:
SELECT
CASE 'amber'
WHEN 'green' THEN 'Go'
WHEN 'amber' THEN 'Slow down'
WHEN 'red' THEN 'Stop'
ELSE 'Unknown'
END;
-- Output: Slow down
In einer echten Abfrage prüfen die Bedingungen Spalten, und CASE fügt dem Ergebnis eine neue Spalte hinzu:
-- Input: orders
-- order_id | amount
-- ---------+--------
-- 1001 | 45.00
-- 1002 | 100.00
-- 1003 | 349.99
-- 1004 | 1250.00
SELECT
order_id,
amount,
CASE
WHEN amount < 100 THEN 'Small'
WHEN amount < 500 THEN 'Medium'
ELSE 'Large'
END AS order_size
FROM orders;
-- Output:
-- order_id | amount | order_size
-- ---------+---------+-----------
-- 1001 | 45.00 | Small
-- 1002 | 100.00 | Medium
-- 1003 | 349.99 | Medium
-- 1004 | 1250.00 | Large
Wichtige Regeln
-
Die erste zutreffende Bedingung gewinnt. Bedingungen werden von oben nach unten geprüft, also setz die engste nach oben. Oben ist
100.00Medium, weilamount < 100falsch undamount < 500wahr ist. In der falschen Reihenfolge erreichen kleine Beträge ihren Zweig nie:
SELECT
CASE
WHEN 45 < 500 THEN 'Medium'
WHEN 45 < 100 THEN 'Small' -- can never win
ELSE 'Large'
END;
-- Output: Medium
- Ohne ELSE ergibt kein Treffer NULL.
SELECT CASE WHEN 72 >= 90 THEN 'Hot' END;
-- Output: NULL
-
Prüf NULL mit IS NULL.
NULL = NULList nicht wahr, deshalb kann die einfache Form kein NULL treffen. Nutz die gesuchte Form:
SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'no match' END;
-- Output: no match
SELECT CASE WHEN NULL IS NULL THEN 'matched' ELSE 'no match' END;
-- Output: matched
- Alle Ergebnisse brauchen einen kompatiblen Typ. Zahl und Text in einem CASE zu mischen schlägt in PostgreSQL und SQL Server fehl, also caste die Zahl:
-- Input: products
-- name | stock
-- -------------+------
-- Desk Lamp | 12
-- Office Chair | 0
SELECT name, CASE WHEN stock > 0 THEN stock ELSE 'Sold out' END AS stock
FROM products;
-- PostgreSQL: ERROR: invalid input syntax for type integer: "Sold out"
-- SQL Server: Conversion failed when converting the varchar value 'Sold out' to data type int.
-- (in MySQL, cast with CAST(stock AS CHAR))
SELECT
name,
CASE WHEN stock > 0 THEN CAST(stock AS VARCHAR(10)) ELSE 'Sold out' END AS stock
FROM products;
-- Output:
-- name | stock
-- -------------+---------
-- Desk Lamp | 12
-- Office Chair | Sold out
Alternative Syntax
Für eine einzelne Bedingung begegnet dir auch eine kürzere Funktion:
-- MySQL
SELECT IF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild
-- SQL Server and SQLite
SELECT IIF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild
Zwei weitere Funktionen sind Kurzformen für gängige CASE-Ausdrücke. COALESCE(nickname, name) bedeutet CASE WHEN nickname IS NOT NULL THEN nickname ELSE name END, und NULLIF(a, b) bedeutet CASE WHEN a = b THEN NULL ELSE a END. Zur ersten siehe die SQL-COALESCE-Anleitung.
MySQL hat außerdem eine CASE-Anweisung für Stored Procedures, die mit END CASE endet. Dieser Beitrag behandelt den CASE-Ausdruck, den du in Abfragen verwendest.
Wann solltest du CASE verwenden?
CASE ist ein Ausdruck und funktioniert daher überall, wo ein Wert stehen kann: in der SELECT-Liste, in ORDER BY und GROUP BY und in Aggregatfunktionen. Auch in WHERE geht es, aber dort sind einfache AND- und OR-Verknüpfungen meist klarer. Die meisten Anwendungsfälle gehören zu einem dieser fünf.
Zahlen in Bereiche einteilen
Mach aus einer Zahl eine Stufe: Preisklassen, Bestellgrößen, Altersgruppen, Noten. Schreib die Bedingungen von einem Ende der Skala zum anderen, damit der erste Treffer der richtige ist.
Codes in Bezeichnungen übersetzen
Datenbanken speichern kurze Codes wie 'A', 'ENG' oder 'gold'; Menschen wollen Wörter. Ein einfaches CASE ordnet jedem Code eine Bezeichnung oder einen Wert wie einen Rabattsatz zu, und ELSE fängt alle unerwarteten Codes ab.
Nur bestimmte Zeilen zählen oder summieren
Setz CASE in COUNT oder SUM, um nur die Zeilen zu zählen oder zu summieren, die eine Bedingung erfüllen. COUNT(CASE WHEN ... THEN 1 END) funktioniert, weil nicht passende Zeilen NULL ergeben, das COUNT überspringt. Ein Aggregat pro Bedingung liefert dir mehrere Summen nebeneinander – so baust du eine Pivot-Tabelle in SQL.
Fehlende Werte behandeln
Prüf Spalten in der bevorzugten Reihenfolge auf NULL und gib eine Bezeichnung zurück, wenn alle leer sind. Für einen einfachen Ersatzwert ist COALESCE kürzer. CASE ist das richtige Werkzeug, wenn jede Art von Lücke ein anderes Ergebnis braucht.
Eigene Sortierreihenfolge
Alphabetische und numerische Reihenfolge passen nicht immer: Kleidergrößen, Ticket-Prioritäten, eine Liste mit hervorgehobenen Produkten zuerst. Ein CASE in ORDER BY gibt jedem Wert die gewünschte Position.
Praxisbeispiele für CASE
Produkte nach Abteilung und Preis einordnen
Ein Ergebnis kann selbst ein CASE sein, sodass jede Abteilung eigene Preisstufen bekommt:
-- Input: products
-- product_name | category | price
-- -----------------+-------------+--------
-- Laptop Pro 14 | Electronics | 1499.00
-- Wireless Earbuds | Electronics | 129.00
-- Leather Jacket | Clothing | 349.00
-- Cotton T-Shirt | Clothing | 19.99
-- Coffee Mug | Kitchen | 12.50
SELECT
product_name,
CASE category
WHEN 'Electronics' THEN
CASE
WHEN price > 1000 THEN 'Premium Electronics'
ELSE 'Standard Electronics'
END
WHEN 'Clothing' THEN
CASE
WHEN price > 200 THEN 'Designer Clothing'
ELSE 'Regular Clothing'
END
ELSE 'Other Products'
END AS product_class
FROM products;
-- Output:
-- product_name | product_class
-- -----------------+---------------------
-- Laptop Pro 14 | Premium Electronics
-- Wireless Earbuds | Standard Electronics
-- Leather Jacket | Designer Clothing
-- Cotton T-Shirt | Regular Clothing
-- Coffee Mug | Other Products
Ab mehr als zwei Ebenen wird verschachteltes CASE schwer lesbar. Eine Lookup-Tabelle, die du joinst, ist meist klarer.
Rabatt nach Kundenstufe anwenden
Jeder Stufen-Code wird einem Rabattsatz zugeordnet, und Kunden ohne Stufe bekommen keinen:
-- Input: customers
-- id | customer_name | tier
-- ---+---------------+-------
-- 1 | Maya Brooks | gold
-- 2 | Leo Martin | silver
-- 3 | Ava Kim | bronze
-- 4 | Noah Price | NULL
-- Input: orders
-- id | customer_id | order_total
-- ----+-------------+------------
-- 101 | 1 | 200.00
-- 102 | 2 | 150.00
-- 103 | 3 | 80.00
-- 104 | 4 | 60.00
SELECT
customer_name,
order_total,
ROUND(order_total * CASE tier
WHEN 'gold' THEN 0.15
WHEN 'silver' THEN 0.10
WHEN 'bronze' THEN 0.05
ELSE 0
END, 2) AS discount
FROM customers c
JOIN orders o ON c.id = o.customer_id
ORDER BY o.id;
-- Output:
-- customer_name | order_total | discount
-- --------------+-------------+---------
-- Maya Brooks | 200.00 | 30.00
-- Leo Martin | 150.00 | 15.00
-- Ava Kim | 80.00 | 4.00
-- Noah Price | 60.00 | 0.00
Monatsumsätze in Spalten pivotieren
Ein SUM(CASE ...) pro Monat macht aus Umsatzzeilen eine Spalte für jeden Monat:
-- Input: sales
-- product_category | sale_date | amount
-- -----------------+------------+-------
-- Books | 2026-01-12 | 40.00
-- Games | 2026-01-20 | 60.00
-- Books | 2026-02-03 | 25.00
-- Books | 2026-03-15 | 30.00
-- Games | 2026-03-28 | 75.00
SELECT
product_category,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar_sales
FROM sales
GROUP BY product_category
ORDER BY product_category;
-- Output:
-- product_category | jan_sales | feb_sales | mar_sales
-- -----------------+-----------+-----------+----------
-- Books | 40.00 | 25.00 | 30.00
-- Games | 60.00 | 0 | 75.00
In SQL Server verwendest du MONTH(sale_date) = 1 statt EXTRACT; in SQLite strftime('%m', sale_date) = '01'.
Fehlende von leeren Werten unterscheiden
Importierte Daten enthalten oft sowohl NULLs als auch leere Strings. CASE kann beide kennzeichnen, damit du weißt, was du bereinigen musst:
-- Input: users
-- id | middle_name
-- ---+------------
-- 1 | Rose
-- 2 |
-- 3 | NULL
SELECT
id,
CASE
WHEN middle_name IS NULL THEN 'Missing'
WHEN middle_name = '' THEN 'Empty'
ELSE middle_name
END AS middle_name
FROM users;
-- Output:
-- id | middle_name
-- ---+------------
-- 1 | Rose
-- 2 | Empty
-- 3 | Missing
Hervorgehobene Produkte zuerst
Gib jeder Kategorie eine Sortierposition und sortiere innerhalb davon nach Namen:
-- Input: products
-- product_name | category
-- -------------+------------
-- Wool Scarf | Sale
-- Desk Lamp | Featured
-- Bike Helmet | Clearance
-- Smart Watch | New Arrival
-- Air Fryer | Featured
SELECT product_name, category
FROM products
ORDER BY
CASE category
WHEN 'Featured' THEN 1
WHEN 'New Arrival' THEN 2
WHEN 'Sale' THEN 3
ELSE 4
END,
product_name;
-- Output:
-- product_name | category
-- -------------+------------
-- Air Fryer | Featured
-- Desk Lamp | Featured
-- Smart Watch | New Arrival
-- Wool Scarf | Sale
-- Bike Helmet | Clearance
Weiterführendes zu CASE
In diesem Blog:
- SQL-COALESCE-Anleitung: der kurze Weg zu einem Ersatzwert, wenn ein Wert NULL ist
- SQL-Pivot-Tabellen-Anleitung: CASE in SUM und AVG, um Zeilen in Spalten zu verwandeln
- SQL-ORDER-BY-Anleitung: Sortieren, auch mit eigener Reihenfolge
- SQL-GROUP-BY-Anleitung: die Gruppierung, auf der bedingte Zählungen und Summen aufbauen
- SQL-Ungleich-Anleitung: warum Vergleiche mit NULL nie zutreffen
Offizielle Dokumentation:
Beekeeper Studio ist eine kostenlose & quelloffene Datenbank-GUI
Das beste SQL-Abfrage- & Editor-Tool, das ich je benutzt habe. Es bietet alles, was ich zum Verwalten meiner Datenbank brauche. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio ist schnell, intuitiv und einfach zu bedienen. Beekeeper unterstützt jede Menge Datenbanken und läuft hervorragend auf Windows, Mac und Linux.
Was Nutzer über Beekeeper Studio sagen
„Beekeeper Studio hat meinen alten SQL-Workflow komplett ersetzt. Es ist schnell, intuitiv und macht die Arbeit mit Datenbanken wieder zum Vergnügen.“
„Ich habe viele Datenbank-GUIs ausprobiert, aber Beekeeper trifft genau die richtige Balance zwischen Funktionsumfang und Einfachheit. Es funktioniert einfach.“