SQL 服务器递归路径 id

SQL server recursion path id

在 SQL 服务器中使用 CTE 递归时,有没有办法显示 SQL 服务器正在使用的路径 ID?

假设我有以下 table 表示相互连接的边:

CREATE TABLE c(id int, n1 int, n2 int);

insert into c( id, n1, n2 ) values ( 100, 1, 2);
insert into c( id, n1, n2 ) values ( 101, 2, 3 );
insert into c( id, n1, n2 ) values ( 102, 3, 4 );
insert into c( id, n1, n2 ) values ( 103, 4, 8 );
insert into c( id, n1, n2 ) values ( 104, 3, 11 );
insert into c( id, n1, n2 ) values ( 105, 11, 12 );

我现在可以使用以下递归查询来显示哪些节点相互连接:

WITH Nodes
AS
(   
    select c.id, c.n1, c.n2, 1 as level from c where id = 100
    UNION ALL   
    select c.id, c.n1, c.n2, level+1 from c inner join Nodes on Nodes.n2 = c.n1 where c.id != 100
)
SELECT id, n1, n2, level from Nodes where level > 1 order by id;

这将给出以下结果:

id  n1  n2  level
101 2   3   2
102 3   4   3
103 4   8   4
104 3   11  3
105 11  12  4

有 2 条路径,101-102-103 和 101-104-105。我想识别每条路径,但我认为它们实际上等于服务器正在使用的递归路径 SQL,所以如果我有办法获取此递归路径 ID,那么我可以识别每个唯一路径。

我希望我的输出看起来像这样:

id  n1  n2  level path_id
101 2   3   2     1
102 3   4   3     1
103 4   8   4     1
104 3   11  3     2
105 11  12  4     2

如您所见,在节点 104 处遇到了第二条路径或递归。这些是构成路径的节点:

path 1 : 101 - 102 - 103
path 2 : 104 - 105

每条路径实际上都从节点 100 开始,但 'level>1' 子句将其排除在结果之外。

谢谢,Steef

如果我没理解错的话,你正在找这样的东西。

数据

CREATE TABLE c(id int, n1 int, n2 int);

insert into c( id, n1, n2 ) values ( 100, 1, 2);
insert into c( id, n1, n2 ) values ( 101, 2, 3 );
insert into c( id, n1, n2 ) values ( 102, 3, 4 );
insert into c( id, n1, n2 ) values ( 103, 4, 8 );
insert into c( id, n1, n2 ) values ( 104, 3, 11 );
insert into c( id, n1, n2 ) values ( 105, 11, 12 );

查询

;WITH Nodes
AS
(   
    select c.id, c.n1, c.n2, 1 as level ,convert(varchar(1000),convert(varchar(1000),id) + '/') as pid
    from c where id = 100
    UNION ALL   
    select c.id, c.n1, c.n2, level+1,convert(varchar(1000),nodes.pid + convert(varchar(1000),c.id) + '/') from c inner join Nodes on Nodes.n2 = c.n1 where c.id != 100
)
SELECT id, n1, n2, level,pid from Nodes where level > 1 order by id;

查询通过将当前 id 附加到列 pid 中的先前节点来显示当前点遍历的完整路径。你需要的输出不是很清楚,如果你能详细说明问题中需要的确切输出,我可以相应地更新我的答案。

编辑 根据你的输出,你可以做这样的事情。

;WITH Nodes
AS
(
    select c.id, c.n1, c.n2, 1 as level ,convert(int,1) as pid
    from c where id = 100
    UNION ALL   
    select c.id, c.n1, c.n2, level+1,convert(int,pid + ROW_NUMBER()OVER(ORDER BY (SELECT 1)) - 1) pid 
    from c inner join Nodes on Nodes.n2 = c.n1 where c.id != 100
)
SELECT id, n1, n2, level,pid from Nodes where level > 1 order by id;