SQL-違いの一部ではないフィールドを取得する
-
29-10-2019 - |
質問
基本的にこのようなことを実行する質問があります。
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
上記のコードがトリックをすると思います。
所属していません StackOverflow