Was tut CASE WHEN?
In der letzten Woche habt ihr bereits das IIF
-Statement kennengelernt und im Zuge dessen auch direkt CASE WHEN
-Statements gesehen. Heute möchten wir die CASE WHEN
-Statements etwas genauer unter die Lupe nehmen. Wie IIF
ist auch CASE WHEN
ein Konstrukt aus dem Bereich der Logik-Funktionen, die es euch ermöglichen, auf bestimmte Werte zu reagieren.
Wofür könnt ihr CASE WHEN verwenden?
Wie schon die IIF
-Funktion, könnt ihr auch CASE WHEN
verwenden, um je nach Wert einer Spalte einen anderen Wert ins Ergebnis zu übernehmen, als Beispiel nehmen wir uns die Abfrage der letzten Woche hinzu:
SELECT StockItemTransactionID ,StockItemID ,TransactionTypeName = CASE TransactionTypeID WHEN 10 THEN 'Stock Issue' WHEN 11 THEN 'Stock Receipt' WHEN 12 THEN 'Stock Adjustment at Stocktake' ELSE 'Unknown' END ,CustomerID ,InvoiceID ,SupplierID ,PurchaseOrderID FROM Warehouse.StockItemTransactions
Nun können wir dieses Statement wie oben schreiben, wir könnten es aber auch umschreiben und die Vergleichsoperation, die hier implizit steht ausschreiben:
SELECT StockItemTransactionID ,StockItemID ,TransactionTypeName = CASE WHEN TransactionTypeID= 10 THEN 'Stock Issue' WHEN TransactionTypeID= 11 THEN 'Stock Receipt' WHEN TransactionTypeID= 12 THEN 'Stock Adjustment at Stocktake' ELSE 'Unknown' END ,CustomerID ,InvoiceID ,SupplierID ,PurchaseOrderID FROM Warehouse.StockItemTransactions
Das Resultat dieser Abfrage ist natürlich dasselbe wie das der ersten Variante. Doch was passiert nun, wenn wir aggregieren wollen über die abgeleiteten Werte? Können wir nach einer Spalte gruppieren, die in einem CASE
-Statement bearbeitet wurde? Ja, in diesem Fall ist das möglich, wie die folgende Abfrage zeigt:
SELECT TransactionTypeName = CASE TransactionTypeID WHEN 10 THEN 'Stock Issue' WHEN 11 THEN 'Stock Receipt' WHEN 12 THEN 'Stock Adjustment at Stocktake' ELSE 'Unknown' END ,AVG(Quantity) FROM Warehouse.StockItemTransactions GROUP BY TransactionTypeID
Das funktioniert dann nicht mehr, wenn in eurem CASE
Statement mehrere Spalten verwendet werden:
SELECT TransactionTypeName = CASE WHEN TransactionTypeID=10 AND Quantity > 0 THEN 'Pos. Stock Issue' WHEN TransactionTypeID=11 AND Quantity > 0 THEN 'Pos. Stock Receipt' WHEN TransactionTypeID=12 AND Quantity > 0 THEN 'Pos. Stock Adjustment' ELSE 'Unknown' END ,AVG(Quantity) FROM Warehouse.StockItemTransactions GROUP BY TransactionTypeID
Diese Abfrage gibt einen Fehler, wenn wir eine derartige Abfrage verwenden möchten, bleibt uns nur, das GROUP BY
anzupassen und auch hier unser CASE
Statement zu verwenden:
SELECT TransactionTypeName = CASE WHEN TransactionTypeID=10 AND Quantity > 0 THEN 'Pos. Stock Issue' WHEN TransactionTypeID=11 AND Quantity > 0 THEN 'Pos. Stock Receipt' WHEN TransactionTypeID=12 AND Quantity > 0 THEN 'Pos. Stock Adjustment' ELSE 'Unknown' END ,AVG(Quantity) FROM Warehouse.StockItemTransactions GROUP BY CASE WHEN TransactionTypeID=10 AND Quantity > 0 THEN 'Pos. Stock Issue' WHEN TransactionTypeID=11 AND Quantity > 0 THEN 'Pos. Stock Receipt' WHEN TransactionTypeID=12 AND Quantity > 0 THEN 'Pos. Stock Adjustment' ELSE 'Unknown' END
Und als Anmerkung: auch wenn die Bedingungen im CASE
Statement identisch sind, müssen auch die Ausgabewerte gleich sein. Das folgende Statement schlägt daher fehl:
SELECT TransactionTypeName = CASE WHEN TransactionTypeID=10 AND Quantity > 0 THEN 'Pos. Stock Issue' WHEN TransactionTypeID=11 AND Quantity > 0 THEN 'Pos. Stock Receipt' WHEN TransactionTypeID=12 AND Quantity > 0 THEN 'Pos. Stock Adjustment at Stocktake' ELSE 'Unknown' END ,AVG(Quantity) FROM Warehouse.StockItemTransactions GROUP BY CASE WHEN TransactionTypeID=10 AND Quantity > 0 THEN 'Case 1' WHEN TransactionTypeID=11 AND Quantity > 0 THEN 'Case 2' WHEN TransactionTypeID=12 AND Quantity > 0 THEN 'Case 3' ELSE 'Unknown' END
Wie schon IIF
gehört auch CASE WHEN
zu den wichtigen Statements um Daten zu modifizieren und die Ausgabe in der Ergebnismenge anzupassen. Anders als die IIF
-Funktion ist das CASE WHEN
-Konstrukt aber im ANSI SQL Standard enthalten und funktioniert sowohl auf allen SQL Server Versionen, die ihr in freier Wildbahn noch antreffen dürftet als auch auf den meisten anderen Relationalen Datenbanksystemen.