Sottoquery (sottoquery) in SQL Server
- 12-09-2022
- Toanngo92
- 0 Comments
Mục lục
Sottoquery (sottoquery)
È possibile utilizzare un’istruzione SELECT o una query per restituire record che verranno utilizzati come criteri per un’altra istruzione o query SELECT. La query esterna è chiamata query padre e la query interna è chiamata subquery. Lo scopo di una sottoquery è restituire i risultati alla query esterna. In altre parole, l’istruzione della query interna deve restituire la colonna o le colonne utilizzate nei criteri della query esterna.
La forma più semplice di una sottoquery è una query che restituisce solo una colonna. La query padre può utilizzare i risultati di questa sottoquery con “=”. Sintassi:
SELECT <ColumnName> FROM <table> WHERE <ColumnName> = (SELECT <ColumnName> FROM <Table> WHERE <ColumnName> = <Condition>)
In una sottoquery, l’istruzione SELECT più interna viene eseguita per prima ei suoi risultati vengono passati come criteri per l’istruzione SELECT esterna.
Considera una situazione in cui è necessario determinare le date di scadenza e di consegna degli ordini più recenti.
Per esempio:
SELECT DueDate,ShipDate FROM Sales.SalesOrderHeader WHERE Sales.SalesOrderHeader.OrderDate = (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader)
Qui è stata utilizzata una sottoquery per ottenere l’output desiderato. La query interna o la sottoquery recupera la data dell’ordine più recente. Questo risultato viene quindi passato a una query esterna, che mostra la data di scadenza e la data di consegna per tutti gli ordini che sono stati evasi in quel particolare giorno.
In base ai risultati restituiti dalla query interna, una sottoquery può essere classificata come una sottoquery scalare ( scalar ) o una query multivalore ( multivalore ).
Sono disponibili le seguenti descrizioni:
- La sottoquery scalare restituisce un singolo valore. Qui, la query esterna deve essere scritta per elaborare un singolo risultato.
- La sottoquery multivalore restituisce lo stesso risultato di una tabella a colonna singola. Qui, la query esterna deve essere scritta per gestire più possibili risultati.
Lavorare con query multivalore
Se l’operatore “=” viene utilizzato con una sottoquery, la sottoquery deve restituire un singolo valore scalare. Se viene restituito più di un valore, si verificherà un errore e la query non verrà elaborata. In questi casi, le parole chiave ANY, ALL, IN ed EXISTS possono essere utilizzate con la clausola WHERE dell’istruzione SELECT quando la query restituisce una colonna ma una o più righe.
Queste parole chiave, note anche come predicati, vengono utilizzate con query multivalore. Si consideri ad esempio che devono essere visualizzati tutti i nomi e cognomi dei dipendenti con la qualifica di ‘Responsabile Ricerca e Sviluppo’. Qui, la query interna può restituire più di una riga, poiché possono esserci più dipendenti con quel titolo di lavoro. Per garantire che la query esterna possa utilizzare i risultati della query interna, sarà necessario utilizzare la parola chiave IN.
Per esempio:
SELECT FirstName,LastName FROM Person.Person WHERE Person.Person.BusinessEntityID IN (SELECT BusinessEntityID FROM HumanResources.Employee WHERE JobTitle='Research and Development Manager');
Quale delle parole chiave SOME o ANY restituisce true se il risultato è una query interna contenente una riga uguale al confronto. Confronta un valore scalare con una colonna di valori. SOME e ANY sono equivalenti, entrambi restituiscono lo stesso risultato. Sono usati raramente.
Alcune linee guida quando si utilizzano sottoquery:
- I tipi di dati ntext, text, image non possono essere utilizzati in SELECT nelle sottoquery
- L’elenco SELECT di sottoquery introdotto con l’operatore di confronto può avere solo un’espressione o un nome di colonna.
- Le sottoquery quando si lavora con operatori di confronto con ANY o ALL keyword non possono utilizzare le clausole GROUP BY e HAVING
- Non è possibile utilizzare la parola chiave DISTINCT con sottoquery che contengono una clausola GROUP BY
- È possibile specificare ORDER BY solo quando viene specificato anche TOP quando si utilizza la query secondaria
Oltre alle sottoquery scalari e multivalore, puoi anche scegliere tra sottoquery indipendenti e sottoquery correlate. Sono definiti come segue:
- La sottoquery autonoma viene scritta come query autonoma, senza alcuna dipendenza dalla query esterna. Una sottoquery indipendente viene elaborata una volta quando viene eseguita la query esterna ei relativi risultati vengono passati alla query esterna.
- Le sottoquery correlate fanno riferimento a una o più colonne della query esterna e quindi dipendono dalla query esterna. Le sottoquery correlate non possono essere eseguite separatamente dalla query esterna.
La parola chiave EXISTS viene utilizzata con la sottoquery per verificare l’esistenza della riga restituita dalla sottoquery. In realtà non restituisce dati e restituisce TRUE o FALSE
La sintassi della sottoquery contenente la parola chiave EXISTS :
SELECT <ColumnName> FROM <table> WHERE [NOT] EXISTS (subquery_statement)
Per esempio:
use AdventureWorks2019 go SELECT FirstName,LastName FROM Person.Person AS p WHERE EXISTS (SELECT * FROM HumanResources.Employee AS e WHERE JobTitle='Research and Development Manager' AND p.BusinessEntityID=e.BusinessEntityID )
Qui, la sottoquery interna recupera tutti i record che corrispondono al titolo di lavoro di “Research and Development Manager” e BusinessEntityID ha un BusinessEntityID che corrisponde a quel record nella tabella Person. Se non sono presenti record che soddisfano entrambe queste condizioni, la sottoquery interna non restituirà alcuna riga. Tuttavia, il codice seguente restituirà due righe perché le condizioni specificate sono soddisfatte.
Allo stesso modo, puoi utilizzare la parola chiave NOT EXISTS , che è la clausola negativa di EXISTS .
Sottoquery nidificate (sottoquery nidificate)
Una sottoquery definita all’interno di un’altra sottoquery è denominata sottoquery nidificata . Considerando la situazione in cui desideri recuperare e visualizzare i nomi delle persone dal Canada in adventureworks2019, non esiste un modo diretto per recuperare queste informazioni perché la tabella Sales.SalesTerritory non è correlata alla tabella Person.Person. Pertanto, una sottoquery annidata può essere la soluzione.
Per esempio:
SELECT LastName, FirstName FROM Person.Person WHERE BusinessEntityID IN (SELECT BusinessEntityID FROM Sales.SalesPerson WHERE TerritoryID IN (SELECT TerritoryID FROM Sales.SalesTerritory WHERE Name='Canada'))
Query correlate (Query correlate)
Nelle query multiple contenenti sottoquery, la sottoquery viene valutata una sola volta per fornire i valori richiesti dalla query padre. Questo perché nella maggior parte delle query, la sottoquery non fa riferimento alla query padre, quindi il valore nella sottoquery rimane lo stesso.
Tuttavia, se la sottoquery fa riferimento alla query padre, la sottoquery deve essere rivalutata per ogni iterazione nella query padre. Questo perché i criteri di ricerca nella sottoquery dipendono dal valore di un particolare record nella query padre.
Quando una sottoquery riceve parametri dalla query padre, viene chiamata sottoquery correlata. Si consideri una situazione in cui si desidera recuperare tutti i BusinessEntityID delle persone le cui informazioni di contatto sono state modificate l’ultima volta dopo il 2012. A tale scopo, è possibile utilizzare la relativa sottoquery come segue:
SELECT a.BusinessEntityID FROM Person.BusinessEntityContact a WHERE a.ContactTypeID IN (SELECT c.ContactTypeID FROM Person.ContactType c WHERE YEAR (a.ModifiedDate) >= 12)
Nel frammento di codice, la query interna recupera gli ID del tipo di contatto per tutte le persone le cui informazioni di contatto sono state modificate l’ultima volta dopo il 2012. Questi risultati vengono quindi passati alla query esterna, che corrisponde a ContactTypeID nella tabella Person.BusinessEntityContact.