Sea*_*ham 6 sql sql-server recursion duplicates
我有一个包含两列ID的表,如下所示:
?????????????????
? Master ? Dupe ?
?????????????????
? 2 ? 7 ?
? 3 ? 6 ?
? 6 ? 7 ?
? 20 ? 25 ?
? 75 ? 25 ?
?????????????????
Run Code Online (Sandbox Code Playgroud)
每行代表sql表中两行的ID,这两行被认为是彼此重复的.
此表可以包含数千个条目,除了Master按照图中按升序排序的列之外,不保证数据.任何一列都可以包含与另一列相同的ID,可能针对不同或相同的合作伙伴ID.再次 - 没有保证.
从这张表中我想获得一个Master的索引及其所有可能的欺骗.如下图所示.
预期的结果:
对于上面的内容,所需的输出看起来像这样(但列不必排序):
?????????????????
? Master ? Dupe ?
?????????????????
? 2 ? 3 ?
? 2 ? 6 ?
? 2 ? 7 ?
? 20 ? 25 ?
? 20 ? 75 ?
?????????????????
Run Code Online (Sandbox Code Playgroud)
我发现很难解释这个问题所以我的谷歌搜索没有太多回复.我认为必须有一个算法来迭代这样的元组列表并发现重复.
任何帮助赞赏!
编辑:我已修改示例表,以更好地解释其内容可能是什么样子.
要考虑的一些注意事项
从我所看到的,问题看起来是递归的,我认为LukStorms是在正确的轨道上,但我无法弄明白
回答:虽然@artm和@LukStorms下面的两个解决方案似乎都有效,但我发现后者更简洁,更易读.谢谢你们俩!一个棘手问题的神奇帮助.我只希望能把答案都给你们两个
下面是一个使用递归 CTE 连接这些重复项的示例。
但为了确保重复项都是双向的,使用了 DUPES CTE。
declare @DuplicateTest table (Master int, Dupe int);
insert into @DuplicateTest (Master, Dupe) values
(3,6),(6,7),(2,7),
(20,25),(75,25);
;with DUPES as
(
select distinct Master as Dupe1, Dupe as Dupe2 from @DuplicateTest
union
select distinct Dupe, Master from @DuplicateTest
)
,RCTE as
(
select Dupe1 as Base, 0 as Level, Dupe1, Dupe2
from DUPES
union all
select r.Base, (r.Level + 1), d.Dupe1, d.Dupe2
from RCTE r
join DUPES d on (r.Dupe2 = d.Dupe1
and r.Dupe1 != d.Dupe2 -- don't loop on the reverse
and r.Base != d.Dupe2 -- don't repeat what we started from
and r.Level < 100) -- if the level gets to big it's most likely a loop
)
select min(Dupe2) as Master, Base as Dupe
from RCTE
group by Base
having Base > min(Dupe2)
order by Base;
Run Code Online (Sandbox Code Playgroud)