2011-12-02 74 views
4

我有類似表: -重複值忽略列順序

+----+---+---+ 
| Id | A | B | 
+----+---+---+  
| 1 | 1 | 2 | 
+----+---+---+ 
| 2 | 2 | 1 | 
+----+---+---+ 
| 3 | 3 | 4 | 
+----+---+---+ 
| 4 | 0 | 5 | 
+----+---+---+ 
| 5 | 5 | 0 | 
+----+---+---+ 

我想刪除所有重複值對的,無論哪個列包含的值,例如之後無論查詢可能是我想看到: -

+----+---+---+ 
| Id | A | B | 
+----+---+---+  
| 1 | 1 | 2 | 
+----+---+---+ 
| 3 | 3 | 4 | 
+----+---+---+ 
| 4 | 0 | 5 | 
+----+---+---+ 

我想找到在Microsoft SQL Server的解決方案(在< = 2005的工作,雖然我很感興趣的任何解決方案,無論如何依靠> = 2008功能)。

此外,請注意,A和B將在1-100範圍內(但這並不是永遠保證的,它們是替代種子整數外鍵,但是外表最多可能會增長到幾百行) 。

我想知道我是否在這裏錯過了一些明顯的解決方案。已發生的所有的人似乎相當過度緊張,但我認爲他們很可能工作,如: -

  • 有一個子查詢返回的位字段與對應的ID之一每一位,並使用這個值刪除重複。
  • 不知何故,透視,刪除重複,然後unpivot。可能會很棘手。

在此先感謝!

+0

這聽起來像一個造型問題太。如果你不在乎哪個值在哪個列中,那麼這兩列代表相同的數據,並且應該被標準化。 – JNK

+0

@JNK - 完全同意,但是在這些情況下通常情況下,此時模型不能修改。 – ljs

回答

5

嘗試:

select min(Id) Id, A, B 
from (select Id, A, B from DuplicatesTable where A <= B 
     union all 
     select Id, B A, A B from DuplicatesTable where A > B) v 
group by A, B 
order by 1 
+0

+1因爲我喜歡在你的子查詢中使用where子句來避免模糊。請注意,子查詢需要一個別名。 – HAdes

+0

我不記得SQLServer是否需要子查詢別名(不是所有的SQL),但我現在已經添加了一個。 –

+0

@MarkBannister - 確實如此 – JNK

6

測試數據和下面的示例。

基本上,我們使用OR標準進行自加入,因此a = a和b = b或a = b和b = a。

子查詢中的WHERE爲您提供每對消除的最大值。

我認爲這應該適用於一式三份(注意我添加了第6行)。

DECLARE @t table(id int, a int, b int) 

INSERT INTO @t 
VALUES 
(1,1,2), 
(2,2,1), 
(3,3,4), 
(4,0,5), 
(5,5,0), 
(6,5,0) 

SELECT * 
FROM @t 
WHERE id NOT IN (
       SELECT a.id 
       FROM @t a 
       INNER JOIN @t b 
        ON (a.a=b.a 
        AND a.b=b.b) 
        OR 
        (a.b=b.a 
        AND a.a = b.b) 
       WHERE a.id > b.id) 
4

不是100%測試,我相信它可以被收拾,但它會產生您想要的結果:

DECLARE @T TABLE (id INT IDENTITY(1,1), A INT, B INT) 

INSERT INTO @T 
VALUES (1,2), (2,1), (3,4), (0,5), (5,0); 

SELECT * 
FROM @T 
WHERE id IN (SELECT DISTINCT MIN(id) 
      FROM (SELECT id, a, b 
        FROM @T 
        UNION ALL 
        SELECT id, b, a 
        FROM @T) z 
      GROUP BY a, b) 
+3

爲什麼使用只返回表格的'CTE'來混淆? – JNK

+0

@JNK:雖然你的'a.a = b.b和a.b = b.a'作爲一個夏日的天空... –

+1

+1因爲參加(A,B)和(B,A)的聯盟是新穎的解決方案。但它不能很好地擴展。 (A,B,C),(A, ,A,B)和(C,B,A)。 JNK的解決方案需要修改JOIN子句。 –