我有一张桌子,如下所示。
表格:
LinkA linkB
--------------------
1 10
10 2
2 5
4 7
6 7
7 3
8 2
3 9
我想在表中找到值的关联。它将链接到具有两个值之一的任何行,然后继续新链接的行。 像这样:
第1行(1,10)->第2行(10,2)->第3行(2,5)->第7行(8,2)。 (1)
第4行(4,7)->第5行(6,7)->第6行(7,3)->第8行(3,9)。 (2)
如何查询这样的表:
LinkA linkB SameLink
-------------------------------
1 10 1
10 2 1
2 5 1
4 7 2
6 7 2
7 3 2
8 2 1
3 9 2
测试表:
create table Data(
linkA INT,
linkB INT );
insert into Data(linkA, linkB)
values ('1', '10'),('10', '2'),('2', '5'),('4', '7'),('6', '7'),('7', '3'),('8', '2'),('3', '9');
答案 0 :(得分:1)
使用CTE进行以下查询可以解决您的问题,只需在第一行中设置参数即可:
DECLARE @Start AS INT = 1;
WITH CTE
AS
(
-- Case Base
SELECT LinkA, LinkB
FROM Data E1
WHERE LinkA = @Start
UNION ALL
-- Recursive Branch
SELECT C.LinkA, E2.LinkB
FROM CTE C
INNER JOIN Data E2
ON C.LinkB = E2.LinkA
)
SELECT *
FROM CTE
ORDER BY LinkA, LinkB;
有关Tips 4 DBs的更多详细信息
答案 1 :(得分:0)
我基于SQL cursor
创建了一个解决方案我还记录了grouping related data into data islands in SQL的解决方案,以提供有关我在下面共享的SQL脚本的更多详细信息
CREATE TABLE RelatedNodes (id int identity(1,1), nodes varchar(max))
DECLARE @LinkA Int
DECLARE @LinkB Int
DECLARE @cnt Int
DECLARE @Nodes1 varchar(max)
DECLARE @Nodes2 varchar(max)
DECLARE @Id1 Int
DECLARE @Id2 Int
DECLARE sqlcursor CURSOR FAST_FORWARD FOR
select
LinkA, LinkB
from Data
Order By LinkA, LinkB
OPEN sqlcursor
FETCH NEXT FROM sqlcursor INTO @LinkA, @LinkB
WHILE @@FETCH_STATUS = 0
BEGIN
---
select
Id
into ##tblId
from RelatedNodes
where
nodes like ('%,' + convert(varchar(max),@LinkA) + ',%') or
nodes like ('%,' + convert(varchar(max),@LinkB) + ',%')
select @cnt = count(*) from ##tblId
if @cnt = 0
begin
insert into RelatedNodes
select
case when @LinkA < @LinkB
then (',' + convert(varchar(max),@LinkA) + ',' + convert(varchar(max),@LinkB) + ',')
else (',' + convert(varchar(max),@LinkB) + ',' + convert(varchar(max),@LinkA) + ',')
end
end
else if @cnt = 1
begin
update RelatedNodes
set nodes = nodes + convert(varchar(max),@LinkA) + ',' + convert(varchar(max),@LinkB) + ','
from RelatedNodes rn
inner join ##tblId t
on rn.id = t.id
end
else if @cnt = 2
begin
select top 1
@Id1 = rn.Id,
@Nodes1 = nodes
from RelatedNodes rn
inner join ##tblId t
on rn.id = t.id
order by t.id
select top 1
@Id2 = rn.Id,
@Nodes2 = nodes
from RelatedNodes rn
inner join ##tblId t
on rn.id = t.id
order by t.id desc
set @Nodes1 = @Nodes1 + @Nodes2
update RelatedNodes
set nodes = @Nodes1
where Id = @Id1
delete RelatedNodes where Id = @Id2
end
drop table ##tblId
FETCH NEXT FROM sqlcursor INTO @LinkA, @LinkB
END
CLOSE sqlcursor
DEALLOCATE sqlcursor
select
LinkA, LinkB, GroupId
from Data
inner join (
select nodes, ROW_NUMBER() over (order by id) as GroupId from RelatedNodes
) g
on g.nodes like ('%,' + convert(varchar(max),LinkA) + ',%')
Order By GroupId, LinkA, LinkB
执行上述SQL脚本的结果如下,为示例数据的所有行提供数据