2011-05-05 36 views
1

我有一個基本上執行類似這樣的查詢:SQL - 設置差別和獲取字段是不差的至少一部分

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

在這個例子中,abc是關鍵這張桌子的領域。 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其中狀態是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。我覺得我缺少的東西在這裏很明顯,但也許我只是太累了,得到它...;)

回答

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

你可以參加所有行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 
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 

我相信上面的代碼會訣竅。