質問

基本的にこのようなことを実行する質問があります。

select a, b, c
from tab
where tab.state = 'A'
minus
select a, b, c
from tab
where tab.state = 'B'

この例では、 a, b, 、 と c このテーブルの重要なフィールドです。 state また、キーの一部であり、州Bではなく状態Aに記録がある状況を見つけようとしています。 value, 、それは異なる州で同じ記録で異なるかもしれません。例:

a  b  c  state  value
---------------------
1  1  1  A      12
1  2  2  A      1002
1  3  9  A      43
1  1  1  B      17.34
1  2  2  B      1002

この場合、私は鍵がある行に興味があります 1,3,9 状態はAです。私もの価値を取得したいと思います value 列、しかし私が試してみると:

select a, b, c, value
from tab
where tab.state = 'A'
minus
select a, b, c, value
from tab
where tab.state = 'B'

私が返されるのは2行です:

a  b  c    value
----------------
1  1  1      12
1  3  9      43

基本的に、私は持ちたいです value 結果セットでは、 minus. 。ここで明らかな何かが足りないように感じますが、多分私はそれを手に入れるにはあまりにも疲れすぎています...;)

役に立ちましたか?

解決

これを行うための明らかな方法は次のようなものです。

select a, b, c, value
from tab
where tab.state = 'A' and not exists (
  select 1                          -- let the optimizer do its thing
  from tab ti
  where tab.state = 'B' and ti.a=tab.a and ti.b=tab.b and ti.c=tab.c)

私も追加します distinct データが2倍になる可能性がある場合、外部クエリで。

他のヒント

すべての行に参加できます state = 'A' と一致するものと state = 'B'...

SELECT t1.a, t1.b, t1.c, t1.value, t2.value v2
FROM (SELECT a, b, c, value FROM tab WHERE state = 'A') t1
     LEFT JOIN (SELECT a, b, c, value FROM tab WHERE state = 'B') t2
            ON t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c

...そして、一致していない行を選びます:

 SELECT a, b, c, value
 FROM ( /* previous query */ )
 WHERE v2 IS NULL
SELECT a,
  b,
  c,
  value
FROM tab tab1
INNER JOIN
  (SELECT a, b, c FROM tab WHERE tab.state = 'A'
  MINUS
  SELECT a, b, c FROM tab WHERE tab.state = 'B'
  ) tab2
ON tab1.a  = tab2.a
AND tab1.b = tab2.b
AND tab1.c = tab2.c 

上記のコードがトリックをすると思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top