SQL Server 2008 R2:避免相反的记录

时间:2015-10-02 07:42:29

标签: sql-server sql-server-2008-r2

我的下表包含两列:

:vv

CREATE TABLE vv
(
    cola INT,
    colb INT
);

插入

INSERT INTO vv VALUES (1,2),(2,1),(3,4),(4,3);

我有记录

SELECT * FROM vv;

Cola    Colb
------------
1   2
2   1
3   4
4   3

注意:现在我想从表中删除反之亦然的记录。就像在我的桌子上一样 记录1,22,1,我只想保留唯一的一个值,无论哪个出现在首位 表

预期结果应为

如果我在SELECT语句中按1订购:

SELECT * FROM vv
ORDER BY CASE WHEN Cola = '1' THEN 1 ELSE 2 END;

结果应为:

Cola    Colb
-------------   
1       2
3       4

如果我在SELECT语句中按4订购:

SELECT * FROM vv
ORDER BY CASE WHEN Cola = '4' THEN 1 ELSE 2 END;

结果应为:

Cola    Colb
-------------
4       3
1       2

如果我在SELECT语句中按3订购:

SELECT * FROM vv
ORDER BY CASE WHEN Cola = '3' THEN 1 ELSE 2 END;

结果应为:

Cola    Colb
-------------   
3       4 
1       2

3 个答案:

答案 0 :(得分:1)

您可以尝试在新列中重新排列它们,然后执行ROW_NUMBERPARTITION BY新列:

WITH Cte AS(
    SELECT *,
        firstCol = CASE WHEN cola >= colb  THEN colb ELSE cola END,
        secondCol = CASE WHEN cola < colb  THEN colb ELSE cola END
    FROM vv
),
CteFinal AS(
    SELECT *,
        rn = ROW_NUMBER() OVER(
                PARTITION BY firstCol, secondCol
                ORDER BY CASE WHEN Cola = '4' THEN 1 ELSE 2 END
             )
    FROM Cte
)
SELECT cola, colb
FROM CteFinal
WHERE rn = 1
ORDER BY CASE WHEN Cola = '4' THEN 1 ELSE 2 END

您必须替换ORDER BY子句才能达到所需的顺序。

答案 1 :(得分:0)

可能的解决方案:

;WITH cte1 AS(SELECT * FROM @vv WHERE cola = 3),
      cte2 AS(SELECT v.* FROM @vv v
              CROSS JOIN cte1 c 
              WHERE NOT ((v.cola = c.colb AND v.colb = c.cola) OR (v.cola = c.cola AND v.colb = c.colb)))
SELECT * FROM cte1
UNION ALL
SELECT c1.* FROM cte2 c1
join cte2 c2 ON c1.cola = c2.colb AND c1.colb = c2.cola AND c1.cola < c2.cola

答案 2 :(得分:0)

如果是我,我会采取以下方法:

1)稍微扭曲创建表格:

CREATE TABLE vv
(
    cola INT,
    colb INT
);

alter table vv add constraint [CK_a_less_than_b] check (cola < colb);
alter table vv add constraint [UQ_a_b] unique (cola, colb);

2)插入通过ff程序发生:

创建过程dbo.insertVV(@a int,@ b int) 作为开始

   if (@a > @b)
      insert into dbo.vv
         (cola, colb)
      values
         (@b, @a);
   else
      insert into dbo.vv
         (cola, colb)
      values
         (@a, @b);
end

或者,如果你不相信那些使用sproc进行插入操作的人,你可以将上面的内容放在一个而不是插入触发器中。

您还可以使用第1步创建一个计算列,该列定义为提供有保证订单的值,然后将唯一索引放在,然后不需要第2步。< / p>