2011-12-02 78 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子句。 –