繁体   English   中英

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

[英]SQL Server 2008 R2: Avoid vice versa records

我有两列的下表:

: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

您可以尝试在新列中重新排列它们,然后在新列中进行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子句才能实现所需的顺序。

可能的解决方案:

;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

如果是我,我将采用以下方法:

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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM