Sottoquery con IN
Il risultato di una subquery introdotta dalla parola chiave IN (o NOT IN) è un elenco di zero o più valori. I risultati restituiti dalla subquery vengono utilizzati dalla query esterna.
Nella seguente query vengono trovati i nomi di tutti i prodotti con nome "Wheels" creati da Adventure Works Cycles.
USE AdventureWorks;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID IN
(SELECT ProductSubcategoryID
FROM Production.ProductSubcategory
WHERE Name = 'Wheels')
Il risultato è il seguente:
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 row(s) affected)
Questa istruzione viene valutata in due fasi: la query interna restituisce il numero di identificazione della sottocategoria corrispondente al nome Wheel (17), dopodiché tale valore viene sostituito nella query esterna, che trova i nomi dei prodotti corrispondenti ai numeri di identificazione di sottocategoria in Product.
USE AdventureWorks;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID in ('17')
L'utilizzo di un join anziché di una subquery per la risoluzione di questo e altri problemi analoghi consente di visualizzare nel risultato colonne che derivano da più tabelle. Se, ad esempio, si desidera includere nel risultato il nome della sottocategoria del prodotto, è necessario utilizzare un join.
Use AdventureWorks;
GO
SELECT p.Name, s.Name
FROM Production.Product p
INNER JOIN Production.ProductSubcategory s
ON p.ProductSubcategoryID = s.ProductSubcategoryID
AND s.Name = 'Wheels'
Il risultato è il seguente:
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 row(s) affected)
Nella seguente query vengono trovati i nomi di tutti i fornitori per i quali si ha un buon classamento creditizio, da cui Adventure Works Cycles ordina almeno 20 prodotti e il cui intervallo medio tra progettazione e produzione è inferiore a 16 giorni.
Use AdventureWorks;
GO
SELECT Name
FROM Purchasing.Vendor
WHERE CreditRating = 1
AND VendorID IN
(SELECT VendorID
FROM Purchasing.ProductVendor
WHERE MinOrderQty >= 20
AND AverageLeadTime < 16)
Il risultato è il seguente:
Name
--------------------------------------------------
Electronic Bike Repair & Supplies
Comfort Road Bicycles
Compete, Inc.
Compete Enterprises, Inc
First Rate Bicycles
First National Sport Co.
Competition Bike Training Systems
Circuit Cycles
Crowley Sport
Expert Bike Co
(10 row(s) affected)
Viene innanzitutto valutata la query interna, la quale restituisce i numeri di identificazione dei fornitori che soddisfano le qualificazioni della subquery. Dopodiché viene valutata la query esterna. Si noti che nella clausola WHERE sia della query interna che di quella esterna è possibile includere più condizioni.
Se si utilizza un join, la stessa query viene formulata nel modo seguente:
USE AdventureWorks;
GO
SELECT DISTINCT Name
FROM Purchasing.Vendor v
INNER JOIN Purchasing.ProductVendor p
ON v.VendorID = p.VendorID
WHERE CreditRating = 1
AND MinOrderQty >= 20
AND AverageLeadTime < 16
Un join può sempre essere espresso come subquery. Spesso, ma non sempre, una subquery può essere espressa come join. Ciò è possibile perché i join sono simmetrici, ovvero l'unione in join delle tabelle A e B restituisce sempre gli stessi risultati indipendentemente dall'ordine delle tabelle nel join. Questo non avviene invece quando si utilizza una subquery.