不同的值忽略列顺序

时间:2011-12-02 16:24:09

标签: sql sql-server

我的表格类似于: -

+----+---+---+
| 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,并使用此值删除重复项。
  • 不知何故,转动,删除重复项,然后取消转储。可能很棘手。

提前致谢!

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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

答案 2 :(得分: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)