Dim*_* Ha 7 sql-server t-sql graph sql-server-2012
我有一个人有几个 ID。其中一些在 Id1 列中,其中一些在 Id2 中。我想将所有相同的人 ID 收集到一组。
如果 id1=10,则与 id2=20 在同一行。所以这意味着id1=10的人与id2=20是同一个人。
输入和输出示例:
Id1 Id2
--- ---
10 20
10 30
30 30
10 40
50 70
60 50
70 70
Run Code Online (Sandbox Code Playgroud)
NewId OldId
----- -----
1 10
1 20
1 30
1 40
2 50
2 60
2 70
Run Code Online (Sandbox Code Playgroud)
最好以迭代的方式进行这样的计算。
这种解决方案的“问题”是,如果源表很大,输出表将包含所有行。但实际上,这也是好处:在源表很大的情况下,这样的代码将比递归运行得更快。
if object_id('tempdb..#src') is not null drop table #src;
create table #src (id1 int not null, id2 int)
if object_id('tempdb..#rez') is not null drop table #rez;
create table #rez (id int not null, chainid int not null);
declare @chainId int;
insert #src
values (10, 20), (10, 30), (30, 30), (10, 40), (50, 70), (60, 50), (70, 70)
--values (4457745,255714),(4457745,2540222),(2540222,4457745),(255714,4457745)
set @chainId = 1
while 1 = 1
begin
insert #rez(id, chainid)
select top 1 id1, @chainId
from #src
where
Id1 NOT IN (select Id from #rez)
and id2 NOT IN (select Id from #rez)
if @@rowcount = 0 break
while 1 = 1
begin
insert #rez(id, chainid)
select id1, @chainid
from #src
where
id2 in (select id from #rez where chainid = @chainId)
and id1 not in (select id from #rez where chainid = @chainId)
union
select id2, @chainId
from #src
where
id1 in (select id from #rez where chainid = @chainId)
and id2 not in (select id from #rez where chainid = @chainId)
if @@rowcount = 0 break
end
select @chainId = @chainId + 1
end
select [NewId] = chainid, OldID = id
from #rez
order by 1, 2;
Run Code Online (Sandbox Code Playgroud)
在一些细节上,脚本的“逻辑”如下:
设置新 ID (chainid) 初始值(例如 1)
获取第一个尚未找到的条目(外部循环)
增加新的ID
查找不在结果表中的下一个条目
继续直到有数据可以工作
返回排序结果
| 归档时间: |
|
| 查看次数: |
219 次 |
| 最近记录: |