2017-10-09 87 views
0

我想查詢包含具有與其他行相反的值的行的數據庫表。所以表看起來像這樣使用反向/交換值抑制行

Src   Trgt   ValueA   ValueB  
A    B    1,44    5 
B    A    1,44    5 <-- 
C    D    1,23    8 
D    C    1,23    8 <-- 
F    G    5,12    9 
G    F    5,12    9 <-- 

我要的是一個返回與源和目標價值交換不再做所有行的查詢。不應該被查詢的行是與另一行具有相同的值A和B的行,但僅與源和目標值交換(上面標記的那些) 因此,期望的結果將如下所示:

Src   Trgt   ValueA   ValueB  
A    B    1,44    5 
C    D    1,23    8 
F    G    5,12    9 
+0

D/E發生了什麼? –

+0

我的錯,更新了桌子。謝謝 – Chris

回答

1

我想這是你想要什麼:

select t.* 
from t 
where t.src < t.trgt 
union all 
select t.* 
from t 
where t.src > t.trgt and 
     not exists (select 1 
        from t t2 
        where t2.src = t.trgt and t2.trgt = t.src and 
         t2.a = t.a and t2.b = t.b 
       ); 

它使遇到的第一行,過濾掉其中的前兩列交換等價行。

編輯:

,如果你只是一個接一個,每個連擊行是另一種方法:

select least(src, trgt) as src, greatest(src, trgt) as trgt, a, b 
from t 
group by least(src, trgt), greatest(src, trgt), a, b; 

這將運行在原始數據不返回行的風險(如果行有沒有重複的和trgt > src

+0

沒有工會沒有辦法做到這一點?如果表t會被廣泛的子查詢切換,我認爲事情會很慢。 – Chris

+0

首先選擇將忽略src = trgt(替換<= <= ???)的記錄,在「exists」之前插入缺少的「not」,Second select將不起作用,因爲a和b未包含在某個聚合函數中!也許可以用窗口函數重寫。 –

+0

@ChristophG。 。 。當src和target相等時,OP沒有聲明該怎麼做。 –

1
SELECT * 
FROM ztable zt 
WHERE zt.source < zt.target -- pick only one of the twins 
OR NOT EXISTS(    -- OR :if it is NOT part of a twin 
     SELECT * 
     FROM ztable nx 
     WHERE nx.source = zt.target 
     AND nx.target = zt.source 
     ); 

假設與source=target AR行不存在或不需要。