T-SQL Ninja #22

CASE WHEN

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.

Referenzen

Ninja-Notebooks @ GitHub

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.