Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL CASE-Anweisung:Was ist das und wie wird es am besten verwendet?

Eine SQL CASE-Anweisung wertet Ergebnisse aus und gibt Ergebnisse basierend auf bestimmten Werten, Prädikaten und Bedingungen gemäß definierter Logik zurück. Angenommen, Sie haben eine Wählertabelle mit den folgenden Details:

  • Wähler-ID
  • Name
  • Geburtstag

Wenn Sie nach Logik zur Wahlberechtigung suchen, hängt diese von den Werten in der Spalte DOB ab.

Wenn das Alter eines Wählers über 18 ist, ist er wahlberechtigt.

Schauen wir uns ein weiteres Beispiel an. Oft speichern wir die Spaltenwerte in den Bits 1 oder 0. Angenommen, Sie speichern die Werte für die Verfügbarkeit eines Produkts als 1 oder 0. Zum Beispiel:

  • 1 =Produkt ist verfügbar
  • 0 =Produkt ist nicht auf Lager

Wenn wir uns die Datenbankperspektive ansehen, ist es eine gute Praxis, die Abkürzungen oder Bits zu verwenden, wo immer dies möglich ist. Dies ist für den SQL Server-Abfrageoptimierer bei der Vorbereitung des optimierten Ausführungsplans von Vorteil. Aus Anwendungssicht benötigt der Endbenutzer diese Werte jedoch nicht. Kunden müssen nur sehen, ob das Produkt verfügbar ist oder nicht.

In der Abbildung unten sehen wir sowohl die Datenbank- als auch die Anwendungsperspektive.

Was macht die SQL CASE-Anweisung?

Eine CASE-Anweisung in SQL Server wertet einen Ausdruck aus und gibt basierend auf den definierten Bedingungen einen Wert zurück. Daher funktionieren die CASE-Anweisungen im vorherigen Beispiel wie unten gezeigt.

Auf hoher Ebene wird die Syntax für eine SQL CASE-Anweisung unten gezeigt. Hier haben wir mehrere Bedingungen angegeben. SQL Server wertet die Bedingungen nacheinander aus. Sobald eine Bedingung erfolgreich ausgewertet wurde, stoppt sie die Auswertung der verbleibenden Bedingungen. Wenn keine der Bedingungen erfüllt ist, können wir eine optionale ELSE-Anweisung verwenden, um den Standardwert zurückzugeben. Wenn wir beispielsweise einen anderen Wert als 0 und 1 in der Verfügbarkeitsspalte haben, erhalten Sie die Ausgabe des ELSE-Codeblocks. Es erfordert mindestens einen Satz der WHEN- und THEN-Blöcke. Die CASE-Anweisung muss mit dem END-Block enden.

Sehen wir uns die SQL CASE-Anweisung anhand verschiedener Beispiele an.

Hinweis:In diesem Artikel verwenden wir die Microsoft-Beispieldatenbank AdventureWorks. Sie können die Sicherung von Microsoft Docs herunterladen.

Die SELECT-Anweisung mit einem einfachen CASE-Ausdruck

In dieser Art von CASE-Anweisung verwenden wir Gleichheitsprüfungsausdrücke. Die folgende Abfrage implementiert einen einfachen CASE-Ausdruck.

  • Wenn der Wert in [SalariedFlag] 1 ist, zeigt es den Aktiven Mitarbeiter
  • Für alle anderen Werte wird die Ausgabe als Inaktiver Mitarbeiter angezeigt
SELECT TOP 5 Nationalidnumber ,
CASE salariedflag
WHEN 1 THEN 'Active Employee'
ELSE 'Inactive Employee'
END AS [Salaried Flag]
FROM [AdventureWorks2019].[HumanResources].[employee]

Wir können mehrere Bedingungen für die CASE-Anweisung angeben.

SELECT TOP 5 Nationalidnumber ,
CASE salariedflag
WHEN 1 THEN 'Active Employee'
WHEN 0 THEN 'Inactive Employee'
ELSE 'Invalid Value'
END AS [Salaried Flag]
FROM [AdventureWorks2019].[HumanResources].[employee]

Datenstandardisierung mit SQL CASE-Anweisungen

Normalerweise verwenden wir Abkürzungen, um Werte in SQL-Tabellen zu speichern. Die Standardabkürzungen sind Geschlecht, Ländercodes, Ehestand, beliebte Produktnamen usw.

Angenommen, wir geben die Abkürzungen zum Speichern des Geschlechts der Mitarbeiter an. Jetzt sollte unsere Anwendung die Ergebnisse ohne Abkürzungen anzeigen.

SQL CASE-Anweisungen helfen, die Ausgabe für definierte Kriterien zu standardisieren. In der folgenden Abfrage verwenden wir die folgenden Bedingungen:

  • Wenn der Geschlechtswert M ist , zeigen Sie es als Männlich an
  • Wenn der Geschlechtswert F ist , zeigen Sie es als Weiblich an
  • Für alle anderen Werte zeigen Sie Ungültig an Wert
SELECT DISTINCT CASE gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
ELSE 'Invalid Value'
END AS Gender
FROM AdventureWorks2019.HumanResources.Employee

Gesuchte CASE-Anweisungen

In der gesuchten CASE-Anweisung geben wir anstelle der direkten Werte einen CASE-Ausdruck an. Sobald der Ausdruckswert eine Bedingung in der WHEN-Klausel auswertet und erfüllt, wird der entsprechende Wert zurückgegeben.

Sehen Sie sich die folgende SQL-Abfrage an. Hier haben wir Ausdrücke in der WHEN-Klausel für [ListPrice] definiert. Es gibt an, dass die Produktkosten 250 $ betragen und ist als Elektronikartikel gekennzeichnet.

SELECT ProductNumber, Name, [Product category] = 
CASE 
WHEN ListPrice = 0 THEN 'Out of Stock items' 
WHEN ListPrice > 0 and ListPrice<=100 THEN 'Consumer goods' 
WHEN ListPrice >100 and ListPrice <= 500 THEN 'Electronics items' 
WHEN ListPrice >500 and ListPrice < 1500 THEN 'Luxury items' 
ELSE 'Extra items' 
END 
FROM Production.Product order by ListPrice desc

Für das zuvor erwähnte Geschlechtsbeispiel können wir die SQL CASE-Anweisung für die Geschlechtsabkürzungen umschreiben, indem wir die gesuchten Groß- und Kleinschreibung verwenden.

SELECT DISTINCT CASE 
WHEN Gender='M' THEN 'Male'
WHEN Gender='F' THEN 'Female'
ELSE 'Invalid Value'
END AS Gender
FROM AdventureWorks2019.HumanResources.Employee

CASE-Anweisungen mit der ORDER BY-Klausel verwenden

SQL-Abfragen verwenden die ORDER BY-Klausel zum Sortieren von Daten in aufsteigender oder absteigender Reihenfolge. Sie können die CASE-Anweisungen in Verbindung mit der ORDER BY-Klausel verwenden. Angenommen, wir rufen aus der Produkttabelle [ProductName] und [ListPrice] ab. Wir möchten die Ergebnisse folgendermaßen sortieren:

  • Wenn der Listenpreis des Produkts weniger als 2.000 beträgt, möchten Sie das Ergebnis in der Standardsortierreihenfolge, d. h. aufsteigend
  • Wenn der Listenpreis des Produkts größer als 2.000 ist, führt die ORDER BY-Klausel zur Sortierung in absteigender Reihenfolge

In dieser Abfrage verwenden wir zwei SQL CASE-Anweisungen, um die Logik zu implementieren.

SELECT Name,
ListPrice
FROM Production.Product
ORDER BY CASE
WHEN ListPrice<=2000 THEN ListPrice END 
,CASE WHEN ListPrice >2000 THEN ListPrice END DESC

In der folgenden Abfrageausgabe können Sie überprüfen, ob die Datensortierungen sowohl in absteigender als auch in aufsteigender Reihenfolge angezeigt werden.

Nehmen wir in einem anderen Beispiel an, wir möchten Daten in der Mitarbeitertabelle basierend auf der folgenden Bedingung sortieren:

  • Für aktive Mitarbeiter (aktuelles Flag =1) sollten die Daten die Einstellungsdatumsspalte sortieren
  • Für inaktive Mitarbeiter sollten die Daten nach den Werten in der Geburtsdatumsspalte sortiert werden
SELECT NationalIDNumber,JobTitle,Hiredate,BirthDate, currentflag
FROM AdventureWorks2019.HumanResources.Employee 
ORDER BY 
CASE CURRENTFLAG WHEN 1 THEN HireDate 
else Birthdate 
end

In der Abfrageausgabe können wir die durch die ORDER BY-Klausel und CASE-Anweisungen definierte Datensortierreihenfolge überprüfen.

CASE-Anweisung in SQL und Aggregatfunktionen

Aggregatfunktionen in SQL Server führen Berechnungen durch und geben einen einzelnen Wert zurück. Beispiele für Aggregatfunktionen sind MIN, MAX, COUNT, ABG und CHECKSUM.

Angenommen, wir möchten die Anzahl der Mitarbeitereinstellungen für jedes Jahr von 2007 bis 2010 abrufen. Die Ergebnisse sollten im folgenden Format angezeigt werden:

Zu diesem Zweck verwenden wir die Aggregatfunktion COUNT in SQL Server.

  • Zunächst filtert die SQL-Funktion DATEPART Daten nach dem Jahr. Beispiel:DATEPART(YY, Hiredate)=2007 filtert Daten für das Jahr 2007.
  • Wir verwenden dann die CASE-Anweisung, um 1 zurückzugeben, wenn das Jahr 2007 ist.
  • Die Zählaggregatfunktion zählt die Datensätze und zeigt die Ergebnisse an.
  • Ähnlich funktioniert die Abfrage für die restlichen Jahre.
SELECT Count(CASE
WHEN Datepart(yy, hiredate) = 2007 THEN 1
ELSE NULL
END) AS [2007Hires],
Count(CASE
WHEN Datepart(yy, hiredate) = 2008 THEN 1
ELSE NULL
END) AS [2008Hires],
Count(CASE
WHEN Datepart(yy, hiredate) = 2009 THEN 1
ELSE NULL
END) AS [2009Hires],
Count(CASE
WHEN Datepart(yy, hiredate) = 2009 THEN 1
ELSE NULL
END) AS [2010Hires]
FROM AdventureWorks2019.HumanResources.Employee

Angenommen, wir möchten die Aggregatfunktion GROUP BY verwenden, um Zeilen mit derselben Produktkategorie zu gruppieren. Wir können die CASE-Anweisung in SQL angeben, um Daten aus der gruppierten Ergebnismenge zu sortieren.

SELECT [Product category] = CASE
WHEN listprice = 0 THEN 'Out of Stock items'
WHEN listprice > 0
AND listprice <= 100 THEN 'Consumer goods'
WHEN listprice > 100
AND listprice <= 500 THEN 'Electronics items'
WHEN listprice > 500
AND listprice < 1500 THEN 'Luxury items'
ELSE 'Extra items'
END,
Min(listprice) AS MinPrice,
Max(listprice) AS MaxPrice,
Count(listprice) AS Numberofproducts
FROM production.product
GROUP BY CASE
WHEN listprice = 0 THEN 'Out of Stock items'
WHEN listprice > 0
AND listprice <= 100 THEN 'Consumer goods'
WHEN listprice > 100
AND listprice <= 500 THEN 'Electronics items'
WHEN listprice > 500
AND listprice < 1500 THEN 'Luxury items'
ELSE 'Extra items'
END
ORDER BY numberofproducts DESC

In der obigen Abfrage verwenden wir zwei SQL CASE-Anweisungen.

  • Die erste CASE-Anweisung kategorisiert die Daten basierend auf dem im Listenpreis definierten Ausdruck. Mit dieser CASE-Anweisung unterteilen wir die Produkte in die folgenden Kategorien:
    • Nicht vorrätige Artikel
    • Konsumgüter
    • Elektronische Artikel
    • Luxusartikel
  • In der zweiten Case-Anweisung verwenden wir die Aggregatfunktion GROUP BY, um das Ergebnis nach Kategorie zu gruppieren
  • Ferner sortieren wir die Ergebnisse nach NumberOfProducts in absteigender Reihenfolge

Dividieren durch Null-Fehler mit SQL CASE-Anweisungen verhindern

Ein Division-durch-Null-Fehler tritt auf, wenn der Nennerwert Null ist. Wenn Sie diese Brüche in SQL Server ausführen, erhalten Sie den Fehler „Division durch Null“, wie unten gezeigt.

Es empfiehlt sich, Ihre Abfragen so zu schreiben, dass diese häufigen Fehler vermieden werden. Um dies zu vermeiden, verwenden wir die Bruchlogik innerhalb einer CASE-Anweisung.

DECLARE @Student1 INT
DECLARE @Student2 INT

SET @Student1=100
SET @Student2=0

select
CASE WHEN @Student2=0
THEN NULL
ELSE @Student1/@Student2 end as StudentMarksRatio

Wir haben unsere Abfrage vor dem Division-durch-Null-Fehler geschützt. Wenn wir nun mit der modifizierten Logik eine Null im Nenner erhalten, erhalten Sie NULL in der Ausgabe, wie unten gezeigt.

Hilfreiche Erinnerungen an die SQL CASE-Anweisung

  • SQL CASE-Anweisungen unterstützen bis zu 10 Verschachtelungsebenen
  • Sie können den Ausführungsfluss der Anweisungen, Funktionen oder Prozeduren nicht mit CASE-Ausdrücken steuern
  • Sie sollten immer einen ELSE-Block verwenden, damit Sie einen Standardwert erhalten, wenn eine Bedingung nicht erfüllt ist
  • Sie sollten widersprüchliche Bedingungen in der SQL CASE-Anweisung vermeiden. Die CASE-Anweisung arbeitet sequentiell und beendet die Auswertung bei der ersten erfolgreichen Bedingung