SQL Deduplicate元组列表

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的索引及其所有可能的欺骗.如下图所示.

预期的结果:

  1. 最低ID应保留为主
  2. 所有随后的欺骗欺骗应该映射回相同(最低ID)的主人

对于上面的内容,所需的输出看起来像这样(但列不必排序):

?????????????????
? Master ? Dupe ?
?????????????????
? 2      ? 3    ?
? 2      ? 6    ?
? 2      ? 7    ?
? 20     ? 25   ?
? 20     ? 75   ?
?????????????????
Run Code Online (Sandbox Code Playgroud)

我发现很难解释这个问题所以我的谷歌搜索没有太多回复.我认为必须有一个算法来迭代这样的元组列表并发现重复.

任何帮助赞赏!

编辑:我已修改示例表,以更好地解释其内容可能是什么样子.

要考虑的一些注意事项

  • 无法保证连锁.它可能都是一个大链条,许多小链条或根本没有.
  • 无法保证所有对在表中的其他位置以相反的顺序出现

从我所看到的,问题看起来是递归的,我认为LukStorms是在正确的轨道上,但我无法弄明白

回答:虽然@artm和@LukStorms下面的两个解决方案似乎都有效,但我发现后者更简洁,更易读.谢谢你们俩!一个棘手问题的神奇帮助.我只希望能把答案都给你们两个

Luk*_*rms 2

下面是一个使用递归 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)