Transact-SQLでの対称差分演算?


10

私はいつもについて知られているUNIONSQLでのオペレータが、ごく最近、他の集合演算子があったことを発見し、INTERSECTそしてEXCEPT。4番目の大きな集合演算子である対称差(たとえば、の逆INTERSECT)を行う演算子を見つけることができませんでした。

私は次のようなものを使用して目的の出力を取得できるようです

SELECT Field FROM A UNION SELECT Field FROM B 
EXCEPT
SELECT Field FROM A INTERSECT SELECT Field FROM B

(私が優先権を正しく持っていると仮定して)、または反完全結合を実行することによって:

SELECT A.Field, B.Field
FROM A
FULL JOIN B ON B.Id = A.Id
WHERE B.Id IS NULL OR A.Id IS NULL

しかし、これらはどちらも、特に他の3つの基本的な集合演算と比較して、かなり集中的なクエリのように見えます。SQLに対称差分演算はありますか?ドキュメントでそれを見つけることができませんか?それとも、T-SQLに実装する「標準的な」方法はありますか?


2
(a EXCEPT b) UNION ALL (b EXCEPT a);より効率的かもしれません。
ypercubeᵀᴹ

3つの結合または結合のような操作を行う@ypercube。これが完全結合よりも効率的である理由は考えられません。
usr 2015年

@usrは、実際には3ではなく、2つのjoin-likeオペレーションです。UnionAllは、はるかにコストのかからないオペレーションです。私はそれFULL JOINがより効率的かもしれないことに同意します。テストにより、どちらが最適かを明らかにできます。そしてもちろん、各テーブルからさらに多くの/異なる列が必要な場合、私のソリューションは簡単に拡張できません。
ypercubeᵀᴹ

回答:


3

すべての集合演算子は、結合または結合のような演算子に変換されます。クエリプランでそれを確認できます。

そのため、そこにある完全外部結合が、最も効率的に実行できます。もちろん、オプティマイザが悪い計画を選択し、書き直しが運によりうまく機能するという、まれにしか発生しない状況は無視してください。これは常に起こり得ます。


それは理にかなっていますが、私が集合演算子を使用する理由は、「追加の列」を作成しないためです...などのことを実行SELECT Id FROM A WHERE <stuff> EXCEPT Select Id FROM A WHERE <other stuff>して、の単一のリストを取得できますId。完全結合でそれを行う方法を理解できません... 2つのId列セットがあることに対処し、それらを自分で結合する必要があるだけですか?
KutuluMike 14

あなたは言うことができますISNULL(a.Col, b.Col) AS Col。それを派生テーブルまたはCTEでラップすると、「折りたたまれた」結果セットを使用して、それをさらに操作できます。(ところで、対称差分演算子が存在する必要があることに同意します。)
usr

2
@MichaelEdenfield一方、compare / distinctで使用されていない他の列が必要な場合はどうでしょうか。結合でそれを行うことができますが、交差/除外ではできません。そのため、場合によっては、バリエーションが実際には最終的にははるかに複雑になることを確認できました。
アーロンバートランド

2

これはかなり良い解決策だと思います。Not Existsサブクエリを使用した2つの選択の間のすべての和集合を使用します。プロジェクションで一致しないフィールドを含めることができるため、UnionとExceptを組み合わせるよりも優れています。

SELECT  'A' TableName, FileType FROM KFX_Inventory I 
    WHERE Not Exists (Select Top 1 1 from KFX_FileType FT WHERE FT.FileType = I.FileType)
UNION ALL
SELECT  'B', FileType FROM KFX_FILEType FT 
    WHERE Not Exists (Select Top 1 1 from KFX_Inventory I WHERE FT.FileType = I.FileType)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.