我有一个基本上执行如下操作的查询:
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
也是密钥的一部分,我正在尝试找到状态A中有记录而不是状态B的情况。还有另一个字段(不在密钥中)我想要报告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
的行感兴趣,其中state为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'
我得到的是两行:
a b c value ---------------- 1 1 1 12 1 3 9 43
基本上,我希望结果集中包含value
,但不参与minus
。我觉得我在这里遗漏了一些明显的东西,但也许我太累了,无法得到它......;)
答案 0 :(得分:3)
这样做的显而易见的方法是:
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
。
答案 1 :(得分:1)
您可以将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
答案 2 :(得分:0)
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
我相信上面的代码可以解决问题。