EXCEPT 和 INTERSECT (Transact-SQL)

比較兩個查詢的結果來傳回個別值。

EXCEPT 會從左側查詢中傳回在右側查詢中找不到的任何個別值。

INTERSECT 會傳回 INTERSECT 運算元左右兩側查詢都傳回的任何個別值。

使用 EXCEPT 或 INTERSECT 的兩個查詢,其結果集的基本組合規則如下:

  • 在所有查詢中,資料行的數目和順序都必須相同。

  • 資料類型必須相容。

主題連結圖示 Transact-SQL 語法慣例

語法

{ <query_specification> | ( <query_expression> ) } 
{ EXCEPT | INTERSECT }
{ <query_specification> | ( <query_expression> ) }

引數

  • <query_specification> | ( <query_expression> )
    這是一個查詢規格或查詢運算式,它會傳回要與另一個查詢規格或查詢運算式資料比較的資料。 EXCEPT 或 INTERSECT 作業中的資料行定義不必相同,但必須能夠透過隱含的轉換來比較。 當資料類型不同時,用來執行比較和傳回結果的類型根據資料類型優先順序的規則來決定。

    當類型相同,但有效位數、小數位數或長度不同時,結果取決於相同的運算式組合規則。 如需詳細資訊,請參閱<有效位數、小數位數和長度 (Transact-SQL)>。

    查詢規格或運算式無法傳回 xml、text、ntext、image 或非二進位 CLR 使用者自訂類型資料行,因為這些資料類型無法比較。

  • EXCEPT
    從 EXCEPT 運算元左側查詢中傳回右側查詢所未傳回的任何個別值。

  • INTERSECT
    傳回 INTERSECT 運算元左右兩側查詢都傳回的任何個別值。

備註

當 EXCEPT 或 INTERSECT 運算元左右兩側查詢傳回的可比較資料行,其資料類型是含不同定序的字元資料類型時,會根據定序優先順序的規則來執行必要的比較。 如果無法執行這項轉換,SQL Server Database Engine 會傳回錯誤。

當您比較資料列來判斷個別值時,兩個 NULL 值會視為相等。

EXCEPT 或 INTERSECT 所傳回之結果集的資料行名稱,與運算元左側查詢傳回的資料行名稱相同。

ORDER BY 子句中的資料行名稱或別名必須參考左側查詢傳回的資料行名稱。

EXCEPT 或 INTERSECT 所傳回的結果集之任何資料行的 Null 屬性,都與運算元左側查詢傳回的對應資料行之 Null 屬性相同。

如果利用 EXCEPT 或 INTERSECT 來搭配運算式中的其他運算子使用,就會依照下列優先順序內容來進行評估:

  1. 括號中的運算式

  2. INTERSECT 運算元

  3. 根據在運算式中的位置,由左至右評估 EXCEPT 和 UNION

如果利用 EXCEPT 或 INTERSECT 來比較超出兩組查詢,每次會比較兩個查詢,且會遵照先前所提及的運算式評估規則,以決定資料類型的轉換。

EXCEPT 和 INTERSECT 無法用在分散式資料分割檢視定義和查詢通知中。

EXCEPT 和 INTERSECT 可用在分散式查詢中,但只能執行於本機伺服器,不會發送到連結伺服器。 因此,在分散式查詢中使用 EXCEPT 和 INTERSECT 可能會影響效能。

當搭配 EXCEPT 或 INTERSECT 作業來使用僅限向前快轉的資料指標和靜態資料指標時,結果集會完整支援這些資料指標。 如果搭配 EXCEPT 或 INTERSECT 作業來使用索引鍵集驅動的資料指標或動態資料指標時,作業結果集的資料指標會轉換成靜態資料指標。

當利用 SQL Server Management Studio 的圖形顯示計畫功能來顯示 EXCEPT 作業時,這項作業會顯示為左方反半聯結,INTERSECT 作業則會顯示成左方半聯結

範例

下列範例會顯示使用 INTERSECT 和 EXCEPT 運算元。 第一個查詢會傳回 Production.Product 資料表的所有值,以便與 INTERSECT 和 EXCEPT 的結果進行比較。

USE AdventureWorks2012;
GO
SELECT ProductID 
FROM Production.Product ;
--Result: 504 Rows

下列查詢會傳回 INTERSECT 運算元左右兩側查詢,都傳回的任何個別值。

USE AdventureWorks2012;
GO
SELECT ProductID 
FROM Production.Product
INTERSECT
SELECT ProductID 
FROM Production.WorkOrder ;
--Result: 238 Rows (products that have work orders)

下列查詢會從 EXCEPT 運算元左側查詢中傳回在右側查詢中找不到的任何個別值。

USE AdventureWorks2012;
GO
SELECT ProductID 
FROM Production.Product
EXCEPT
SELECT ProductID 
FROM Production.WorkOrder ;
--Result: 266 Rows (products without work orders)

下列查詢會從 EXCEPT 運算元左側查詢中傳回在右側查詢中找不到的任何個別值。 資料表是由先前範例反轉所得。

USE AdventureWorks2012;
GO
SELECT ProductID 
FROM Production.WorkOrder
EXCEPT
SELECT ProductID 
FROM Production.Product ;
--Result: 0 Rows (work orders without products)