Unterabfragen mit IN
Das Ergebnis einer mit IN (oder mit NOT IN) eingeleiteten Unterabfrage entspricht einer Liste aus null oder mehr Werten. Sobald die Unterabfrage Ergebnisse zurückgibt, werden diese von der äußeren Abfrage verwendet.
Die folgende Abfrage sucht die Namen aller Wheel-Produkte, die Adventure Works Cycles herstellt.
USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE Name = 'Wheels');
Im Folgenden wird das Ergebnis aufgeführt:
Name
----------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
HL Mountain Front Wheel
LL Road Front Wheel
ML Road Front Wheel
HL Road Front Wheel
Touring Front Wheel
LL Mountain Rear Wheel
ML Mountain Rear Wheel
HL Mountain Rear Wheel
LL Road Rear Wheel
ML Road Rear Wheel
HL Road Rear Wheel
Touring Rear Wheel
(14 Zeile(n) betroffen)
Diese Anweisung wird in zwei Schritten ausgewertet. Die innere Abfrage gibt zunächst die Unterkategorie-ID zurück, die dem Namen "Wheel" entspricht (17). Danach wird dieser Wert in die äußere Abfrage eingesetzt, die die zu den Unterkategorie-IDs gehörenden Produktnamen in Product findet.
USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID IN ('17');
Beim Verwenden eines Joins statt einer Unterabfrage zeigt sich u. a. folgender Unterschied: Wenn Sie für dieses und ähnliche Probleme einen Join statt einer Unterabfrage verwenden, können Sie im Ergebnis die Spalten aus mehreren Tabellen anzeigen. Wenn Sie beispielsweise den Namen der Produktunterkategorie in die Ergebnisse einschließen möchten, müssen Sie die Variante mit dem Join verwenden.
Use AdventureWorks2008R2;
GO
SELECT p.Name, s.Name
FROM Production.Product p
INNER JOIN Production.ProductSubcategory s
ON p.ProductSubcategoryID = s.ProductSubcategoryID
AND s.Name = 'Wheels';
Im Folgenden wird das Ergebnis aufgeführt:
Name Name
LL Mountain Front Wheel Wheels
ML Mountain Front Wheel Wheels
HL Mountain Front Wheel Wheels
LL Road Front Wheel Wheels
ML Road Front Wheel Wheels
HL Road Front Wheel Wheels
Touring Front Wheel Wheels
LL Mountain Rear Wheel Wheels
ML Mountain Rear Wheel Wheels
HL Mountain Rear Wheel Wheels
LL Road Rear Wheel Wheels
ML Road Rear Wheel Wheels
HL Road Rear Wheel Wheels
Touring Rear Wheel Wheels
(14 Zeile(n) betroffen)
Die folgende Abfrage sucht die Namen aller Hersteller, deren Bonität gut ist, bei denen Adventure Works Cycles mindestens 20 Artikel bestellt und deren durchschnittliche Vorlaufzeit bei Lieferungen 16 Tage beträgt.
Use AdventureWorks2008R2;
GO
SELECT Name
FROM Purchasing.Vendor
WHERE CreditRating = 1
AND BusinessEntityID IN
(SELECT BusinessEntityID
FROM Purchasing.ProductVendor
WHERE MinOrderQty >= 20
AND AverageLeadTime < 16);
Im Folgenden wird das Ergebnis aufgeführt:
Name
--------------------------------------------------
Compete Enterprises, Inc
International Trek Center
First National Sport Co.
Comfort Road Bicycles
Circuit Cycles
First Rate Bicycles
Jeff's Sporting Goods
Competition Bike Training Systems
Electronic Bike Repair & Supplies
Crowley Sport
Expert Bike Co
Team Athletic Co.
Compete, Inc.
(13 Zeile(n) betroffen)
Die innere Abfrage wird ausgewertet und gibt die IDs der Hersteller zurück, die den Bedingungen der Unterabfrage entsprechen. Danach wird die äußere Abfrage ausgewertet. Beachten Sie, dass Sie in den WHERE-Klauseln der inneren und äußeren Abfrage mehrere Bedingungen einschließen können.
Mit einem Join kann dieselbe Abfrage folgendermaßen ausgedrückt werden:
USE AdventureWorks2008R2;
GO
SELECT DISTINCT Name
FROM Purchasing.Vendor v
INNER JOIN Purchasing.ProductVendor p
ON v.BusinessEntityID = p.BusinessEntityID
WHERE CreditRating = 1
AND MinOrderQty >= 20
AND AverageLeadTime < 16;
Ein Join kann immer als Unterabfrage ausgedrückt werden. Demgegenüber kann eine Unterabfrage zwar häufig, jedoch nicht immer als Join ausgedrückt werden. Die Ursache hierfür liegt in der Symmetrie von Joins: Sie können die Tabellen A und B in beliebiger Reihenfolge verknüpfen und erhalten immer dieselben Ergebnisse. Dies gilt nicht, wenn eine Unterabfrage verwendet wird.