Nozioni fondamentali sulle sottoquery
Una sottoquery è una query nidificata in un'istruzione SELECT, INSERT, UPDATE o DELETE o in un'altra sottoquery. È possibile utilizzare una sottoquery in qualsiasi posizione in cui è consentito inserire un'espressione. In questo esempio una sottoquery viene utilizzata come espressione di colonna MaxUnitPrice in un'istruzione SELECT.
USE AdventureWorks2008R2;
GO
SELECT Ord.SalesOrderID, Ord.OrderDate,
(SELECT MAX(OrdDet.UnitPrice)
FROM AdventureWorks.Sales.SalesOrderDetail AS OrdDet
WHERE Ord.SalesOrderID = OrdDet.SalesOrderID) AS MaxUnitPrice
FROM AdventureWorks2008R2.Sales.SalesOrderHeader AS Ord
Le sottoquery sono dette anche query interne o istruzioni SELECT interne. L'istruzione che include una sottoquery è detta anche query esterna o istruzione SELECT esterna.
Molte istruzioni Transact-SQL che includono sottoquery possono essere formulate anche come join. Altre domande possono essere poste solo in forma di sottoquery. In Transact-SQL non si rileva in genere alcuna differenza nelle prestazioni tra un'istruzione che include una sottoquery e una versione equivalente dal punto di vista semantico ma priva di sottoquery. In alcuni casi in cui è necessario verificare l'esistenza di dati specifici, tuttavia, l'utilizzo di un join consente di ottenere prestazioni migliori. Se non si utilizza un join, è necessario assicurarsi che i duplicati vengano eliminati elaborando la query nidificata per ogni risultato della query esterna. In questi casi, l'utilizzo del join consente di ottenere risultati migliori. Nell'esempio seguente vengono illustrate un'istruzione SELECT con una sottoquery e un'istruzione SELECT con un join che restituiscono lo stesso set di risultati:
/* SELECT statement built using a subquery. */
SELECT Name
FROM AdventureWorks2008R2.Production.Product
WHERE ListPrice =
(SELECT ListPrice
FROM AdventureWorks2008R2.Production.Product
WHERE Name = 'Chainring Bolts' );
/* SELECT statement built using a join that returns
the same result set. */
SELECT Prd1. Name
FROM AdventureWorks2008R2.Production.Product AS Prd1
JOIN AdventureWorks2008R2.Production.Product AS Prd2
ON (Prd1.ListPrice = Prd2.ListPrice)
WHERE Prd2. Name = 'Chainring Bolts';
Una sottoquery nidificata nell'istruzione SELECT esterna include i componenti seguenti:
Una normale query SELECT che include i componenti normalmente specificati in un elenco di selezione.
Una normale clausola FROM che include uno o più nomi di tabelle o viste.
Una clausola WHERE facoltativa.
Una clausola GROUP BY facoltativa.
Una clausola HAVING facoltativa.
La query SELECT di una sottoquery è sempre racchiusa tra parentesi. Non può includere una clausola COMPUTE o FOR BROWSE. È consentita solo una clausola ORDER BY se è specificata anche una clausola TOP.
Una sottoquery può essere nidificata nella clausola WHERE o HAVING di un'istruzione SELECT, INSERT, UPDATE o DELETE esterna oppure in un'altra sottoquery. Sono consentiti fino a 32 livelli di nidificazione. Il limite massimo tuttavia varia in base alla memoria disponibile e alla complessità delle altre espressioni della query, ovvero alcune query specifiche potrebbero non supportare 32 livelli di nidificazione. Una sottoquery può essere specificata in qualsiasi posizione in cui è consentito inserire un'espressione, a condizione che venga restituito un solo valore.
Se una tabella viene specificata in una sottoquery e non nella query esterna, le colonne di tale tabella non vengono inserite nell'output, ovvero nell'elenco di selezione della query esterna.
Le istruzioni che includono una sottoquery vengono in genere formulate in uno dei formati seguenti:
WHERE expression [NOT] IN (subquery)
WHERE expression comparison_operator [ANY | ALL] (subquery)
WHERE [NOT] EXISTS (subquery)
In alcune istruzioni Transact-SQL la sottoquery può essere valutata come se si trattasse di una query indipendente. Concettualmente i risultati della sottoquery vengono sostituiti nella query esterna, anche se ciò non corrisponde all'effettiva modalità di elaborazione delle istruzioni Transact-SQL con sottoquery in Microsoft SQL Server.
Sono disponibili tre tipi di sottoquery di base, ovvero:
Sottoquery applicate agli elenchi introdotte da IN oppure introdotte da un operatore di confronto modificato da ANY o ALL.
Sottoquery introdotte da un operatore di confronto non modificato le quali devono restituire un solo valore.
Sottoquery che corrispondono a test di esistenza introdotte da EXISTS.