EXCEPT および INTERSECT (Transact-SQL)
2 つのクエリの結果を比較して、個別の値を返します。
EXCEPT は、左のクエリにあって右のクエリにない個別の値を返します。
INTERSECT は、INTERSECT オペランドの左右両方のクエリによって返される個別の値を返します。
EXCEPT と INTERSECT を使用して 2 つのクエリの結果セットを結合する場合の基本的な規則は、次のとおりです。
列の数と順番は、すべてのクエリで同じであること
データ型に互換性があること
構文
{ <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 データベース エンジンではエラーが返されます。
個別の値を決定するために行を比較するとき、2 つの NULL 値は等しいと見なされます。
EXCEPT または INTERSECT で返される結果セットの列名は、オペランドの左のクエリで返されるものと同じ名前になります。
ORDER BY 句の列名または列の別名は、左のクエリで返される列名を参照している必要があります。
EXCEPT または INTERSECT で返される結果セットの列で NULL 値が許容されるかどうかは、オペランドの左のクエリで返される対応する列の設定と同じになります。
EXCEPT または INTERSECT を、他の演算子と共に 1 つの式で使用する場合、評価は次の優先順で行われます。
かっこで囲まれた式
INTERSECT オペランド
EXCEPT と UNION (式の中の位置に基づいて、左から右の順に評価)
EXCEPT または INTERSECT を使用して 2 つ以上のクエリのセットを比較する場合、データ型の変換は、2 つのクエリを一度比較し、前に説明した式の評価の規則に従って決定されます。
EXCEPT と INTERSECT は、分散パーティション ビュー定義やクエリ通知では使用できません。
EXCEPT と INTERSECT は分散クエリで使用できますが、この場合ローカル サーバーでのみ実行され、リンク サーバーにはプッシュされません。 したがって、EXCEPT と INTERSECT を分散クエリで使用すると、パフォーマンスに影響が生じる可能性があります。
高速順方向専用カーソルと静的カーソルを、EXCEPT または INTERSECT 演算で使用した場合、これらのカーソルは結果セットで完全にサポートされます。 キーセットドリブン カーソルまたは動的カーソルを、EXCEPT または INTERSECT 演算で使用した場合、演算の結果セットのカーソルは静的カーソルに変換されます。
EXCEPT 演算が、SQL Server Management Studio のグラフィカル プラン表示機能を使用して表示される場合、この演算は Left Anti Semi Join として表示され、INTERSECT 演算は Left Semi Join として表示されます。
使用例
次の例では、INTERSECT および EXCEPT オペランドの使用方法を示します。 最初のクエリでは、INTERSECT および EXCEPT の結果と比較するため、Production.Product テーブルからすべての値を返します。
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)