Filtern von Daten mit Prädikaten
Die einfachsten SELECT-Anweisungen mit ausschließlich SELECT- und FROM-Klauseln werten jede Zeile in einer Tabelle aus. Mithilfe einer WHERE-Klausel legen Sie Bedingungen fest, die bestimmen, welche Zeilen verarbeitet werden und die das Resultset möglicherweise reduzieren.
Die Struktur der WHERE-Klausel
Die WHERE-Klausel besteht aus mindestens einer Suchbedingung. Alle Suchbedingungen müssen für jede Zeile der Tabelle in TRUE, FALSE oder „unknown“ (unbekannt) ausgewertet werden. Es werden nur Zeilen zurückgegeben, wenn die WHERE-Klausel als TRUE ausgewertet wird. Die einzelnen Bedingungen wirken wie Filter auf die Daten und werden als „Prädikate“ bezeichnet. Jedes Prädikat enthält eine Bedingung, die getestet wird, in der Regel mithilfe der grundlegenden Vergleichsoperatoren:
- = (ist gleich)
- <> (ungleich)
- > (größer als)
- >= (größer als oder gleich)
- < (kleiner als)
- <= (kleiner als oder gleich)
Die folgende Abfrage gibt beispielsweise alle Produkte mit dem ProductCategoryID-Wert 2 zurück:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2;
Entsprechend gibt die folgende Abfrage alle Produkte mit einem ListPrice-Wert kleiner als 10.00 zurück:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice < 10.00;
IS NULL/IS NOT NULL
Sie können auch einfach filtern, um „unbekannte“ oder NULL-Werte zuzulassen oder auszuschließen, indem Sie IS NULL oder IS NOT NULL verwenden.
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductName IS NOT NULL;
Mehrere Bedingungen
Mehrere Prädikate können mit den Operatoren AND und OR und mit Klammern kombiniert werden. Allerdings verarbeitet SQL Server nur zwei Bedingungen gleichzeitig. Alle Bedingungen müssen TRUE ergeben, wenn Sie mehrere Bedingungen mit dem Operator AND verknüpfen. Wenn Sie den Operator OR verwenden, um zwei Bedingungen zu verknüpfen, kann eine oder es können beide für das Resultset TRUE sein.
Die folgende Abfrage gibt beispielsweise ein Produkt in Kategorie 2 zurück, das weniger als 10.00 kostet:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2
AND ListPrice < 10.00;
AND-Operatoren werden vor OR-Operatoren verarbeitet, sofern keine Klammern verwendet werden. Als bewährte Methode sollten Sie Klammern verwenden, wenn Sie mehr als zwei Prädikate verwenden. Die folgende Abfrage gibt Produkte in Kategorie 2 OR 3 AND bei Kosten unter 10,00 zurück:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE (ProductCategoryID = 2 OR ProductCategoryID = 3)
AND (ListPrice < 10.00);
Vergleichsoperatoren
Transact-SQL umfasst Vergleichsoperatoren, die die WHERE-Klausel vereinfachen können.
IN
Der IN-Operator ist eine Kurzform für mehrere Gleichheitsbedingungen für dieselbe Spalte, die mit OR verbunden sind. Es spricht nichts dagegen, mehrere OR-Bedingungen in einer Abfrage zu verwenden, wie im folgenden Beispiel:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2
OR ProductCategoryID = 3
OR ProductCategoryID = 4;
Die Verwendung von IN ist jedoch eindeutig und prägnant, und die Leistung der Abfrage wird nicht beeinträchtigt.
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID IN (2, 3, 4);
BETWEEN
BETWEEN ist eine weitere Verknüpfung, die Sie verwenden können, wenn Sie nach einer oberen und unteren Grenze für den Wert filtern, anstatt zwei Bedingungen mit dem AND-Operator zu verwenden. Die folgenden beiden Abfragen sind gleichwertig:
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice >= 1.00
AND ListPrice <= 10.00;
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice BETWEEN 1.00 AND 10.00;
Der BETWEEN-Operator verwendet inklusive Begrenzungswerte. Produkte mit einem Preis von 1.00 oder 10.00 würden in die Ergebnisse einbezogen. BETWEEN ist auch bei der Abfrage von Datumsfeldern hilfreich. Die folgende Abfrage enthält z. B. alle Produktnamen, die zwischen dem 1. Januar 2012 und dem 31. Dezember 2012 geändert wurden:
SELECT ProductName, ModifiedDate
FROM Production.Product
WHERE ModifiedDate BETWEEN '2012-01-01' AND '2012-12-31';
ProductName
ModifiedDate
Mountain Bike Socks, M
2012-01-01 00:00:00.000
HL Mountain Frame - Silver, 42
2012-03-05 00:00:00.000
HL Mountain Frame - Silver, 38
2012-08-29 00:00:00.000
Mountain-100 Silver, 38
2012-12-31 00:00:00.000
Da wir jedoch keinen Zeitbereich angeben, werden keine Ergebnisse nach 2012-12-31 00:00:00.000 zurückgegeben. Um Datum und Uhrzeit genau zu erfassen, müssen wir die Uhrzeit in das Prädikat aufnehmen:
SELECT ProductName, ListPrice, ModifiedDate
FROM Production.Product
WHERE ModifiedDate BETWEEN '2012-01-01 00:00:00.000' AND '2012-12-31 23:59:59.999';
Grundlegende Vergleichsoperatoren wie „Größer als“ (>) und „Gleich“ (=) sind auch genau, wenn Sie nur nach Datum filtern:
SELECT ProductName, ListPrice, ModifiedDate
FROM Production.Product
WHERE ModifiedDate >= '2012-01-01'
AND ModifiedDate < '2013-01-01';
LIKE
Der letzte Vergleichsoperator kann nur für Zeichendaten verwendet werden und ermöglicht die Verwendung von Platzhalterzeichen und Mustern für reguläre Ausdrücke. Platzhalter ermöglichen es, Teilzeichenfolgen anzugeben. Beispielsweise können Sie die folgende Abfrage verwenden, um alle Produkte mit Namen zurückzugeben, die das Wort „mountain“ enthalten:
SELECT Name, ListPrice
FROM SalesLT.Product
WHERE Name LIKE '%mountain%';
Der Platzhalter % stellt eine beliebige Zeichenfolge mit 0 oder mehr Zeichen dar, sodass die Ergebnisse Produkte mit dem Wort „mountain“ an einer beliebigen Stelle in ihrem Namen enthalten, wie hier gezeigt:
Name
ListPrice
Mountain Bike Socks, M
9,50
Mountain Bike Socks, L
9,50
HL Mountain Frame - Silver, 42
1364.0
HL Mountain Frame - Black, 42
1349.60
HL Mountain Frame - Silver, 38
1364.50
Mountain-100 Silver, 38
3399.99
Sie können den Platzhalter _ (Unterstrich) verwenden, um ein einzelnes Zeichen wie folgt darzustellen:
SELECT ProductName, ListPrice
FROM SalesLT.Product
WHERE ProductName LIKE 'Mountain Bike Socks, _';
Die folgenden Ergebnisse enthalten nur Produkte, die mit „Mountain Bike Socks, “ und einem einzelnen anschließenden Zeichen beginnen:
ProductName
ListPrice
Mountain Bike Socks, M
9,50
Mountain Bike Socks, L
9,50
Sie können auch komplexe Muster für Zeichenfolgen definieren, nach denen Sie suchen möchten. Die folgende Abfrage suchte z. B. nach Produkten mit einem Namen, der mit „Mountain-“ beginnt, gefolgt von:
- Drei Zeichen zwischen 0 und 9
- Eine Leerstelle
- Einer beliebigen Zeichenfolge
- Einem Komma
- Eine Leerstelle
- Zwei Zeichen zwischen 0 und 9
SELECT ProductName, ListPrice
FROM SalesLT.Product
WHERE ProductName LIKE 'Mountain-[0-9][0-9][0-9] %, [0-9][0-9]';
Die Ergebnisse dieser Abfrage könnte ungefähr wie folgt aussehen:
ProductName
ListPrice
Mountain-100 Silver, 38
3399.99
Mountain-100 Silver, 42
3399.99
Mountain-100 Black, 38
3399.99
Mountain-100 Black, 42
3399.99
Mountain-200 Silver, 38
2319.99
Mountain-200 Silver, 42
2319.99
Mountain-200 Black, 38
2319.99
Mountain-200 Black, 42
2319.99