2017-06-22 7 views
1

私は select文が、両方ではないのいずれかに行が属する2つのselect文、(すべての列が一致する場合)のすべての行を見つけたいです。オラクルMINUS両方の方法(選択の違いを取得)

私は、これは、fooは最初のselect文ではなく、周りの最後が、他のではない方法で、存在するすべての行を返す単一方向

select foo from foobar where bar = 1 
minus 
    select foo from foobar where bar = 2; 

でこれをで達成する方法を知っています。

私は望ましい結果を返す

(select foo from foobar where bar = 1 
    minus 
    select foo from foobar where bar = 2) 
union 
    (select foo from foobar where bar = 2 
    minus 
    select foo from foobar where bar = 1); 

を行うことができます知っています。しかし、これは多くの繰り返しです。両方の方法で動作するminusのような演算子がありますか?

また、結果に識別子を追加して、それがどの選択項目に属するかを示したいと思います。しかし、これだけでは、すべての行が異なるようになります。

+0

誤解を招くが、 'bar = 1'が' bar = 2'(または他の値)のレコードと暗黙的に区別されるレコードはありませんか?たぶん、より良い例で更新するべきでしょう。 –

+0

私はすべての列を返すわけではありませんが、特定の列(バーに関係なく共通または異なる可能性があります) –

+0

実際のサンプルデータをここに表示すると他の人に役立つかもしれません。スタックオーバーフローに関するSQLクエリーに関する質問には、数千語の価値があります。 –

答えて

1

SET演算子は、いずれかのクエリによって全て 含むいずれかのクエリによって選択

UNION ALLすべての行を、選択されたすべての個別の行のみ

UNIONである

により選択されたすべての個別の行に交差複製します両方のクエリ

MINUS最初のクエリで選択されたすべての個別の行が、2番目のクエリでは選択されていません。

01あなたが使用することができ

交差するが、2つの行セットは、(彼らはテーブルや他の計算の結果を基礎とする)は、既に重複除外されている場合は選択の数は、あなたができる、pratically同じ

(select foo from foobar where bar = 1 
    union 
    select foo from foobar where bar = 2) 
    minus 
    (select foo from foobar where bar = 1 
    intesect 
    select foo from foobar where bar = 2) 
1

ですuse

特に、ローセットがベーステーブルの場合は、それぞれが2回ではなく1回だけスキャンされるという利点があります。

すでに結果セットが重複除外されていない場合は、select fooselect distinct fooに変更することができます。

各結果セットに重複があり、両方のテーブルに共通であるが異なる多重度を持つ行(foo値)を表示する場合も同様の解決策があります(たとえば、1つの行セットで3つの重複もう一方は5つの重複)。この場合

1

(常に同じ表)あなたは、単に集約することができます:

select foo, max(bar) 
from foobar 
where bar in (1,2) 
group by foo 
having count(distinct bar) = 1; 

これはあなただけのいずれかのバー1またはバー2とないの両方を持っているすべてのfooを与えます。 max(bar)は、fooに2つの値のどちらがあるかを示します。

関連する問題