我的下表包含两列:
表: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,2
和2,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
答案 0 :(得分:1)
您可以尝试在新列中重新排列它们,然后执行ROW_NUMBER
和PARTITION 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>