相互關聯子查詢

許多查詢都可藉著執行一次子查詢,並將產生的數值或多個數值替換至外部查詢的 WHERE 子句來進行運算。在包含相互關聯子查詢的查詢中 (也就是重複的子查詢),子查詢值將取決於外部查詢。這代表子查詢將重複執行,每個可能會被外部查詢所選取的資料列都執行一次。

這個查詢會對在 SalesPerson 資料表中獎金為 5000 且員工識別碼在 Employee 和 SalesPerson 資料表中都相符的每個員工,擷取一份每個員工的姓名。

USE AdventureWorks2008R2;
GO
SELECT DISTINCT c.LastName, c.FirstName, e.BusinessEntityID 
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID 
WHERE 5000.00 IN
    (SELECT Bonus
    FROM Sales.SalesPerson sp
    WHERE e.BusinessEntityID = sp.BusinessEntityID) ;
GO

以下為結果集:

LastName FirstName BusinessEntityID

-------------------------- ---------- ------------

Ansman-Wolfe Pamela 280

Saraiva José 282

(2 個資料列受到影響)

這個陳述式中先前的子查詢無法在外部查詢之外獨立評估。它需要 Employee.BusinessEntityID 值,但是在 SQL Server 檢查 Employee 中不同的資料列時,這個值會變更。

此查詢的確實運算方式是:SQL Server 會先考慮 Employee 資料表的每個資料列,以便藉著將每個資料列的數值替代至內部查詢中來將它包含在結果之中。例如,如果 SQL Server 先檢查 Syed Abbas 的資料列,則變數 Employee.BusinessEntityID 會採用值 285,表示 SQL Server 會替代至內部查詢中。

USE AdventureWorks2008R2;
GO
SELECT Bonus
FROM Sales.SalesPerson
WHERE BusinessEntityID = 285;

結果為 0 (因為 Syed Abbas 不是業務人員,所以未收到任何獎金),因此外部查詢會評估為:

USE AdventureWorks2008R2;
GO
SELECT LastName, FirstName
FROM Person.Person AS c JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID 
WHERE 5000 IN (0.00)

因為此結果為 false,Syed Abbas 資料列將不會包含於結果之中。進行和 Pamela Ansman-Wolfe 的資料列相同的程序。您將會在結果中看到包含這個資料列。

藉由參考外部查詢中的資料表資料行做為資料表值函式的引數,相互關聯的子查詢也可以將資料表值函式併入 FROM 子句中。在上述情形中,針對外部查詢的每個資料列,會根據子查詢估算資料表值函式。