2015-04-24 99 views
2

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

比方说,我有一个代表相互连接的边缘如下表:

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条路径s,101-102-103 & 101-104-105。我想识别每条路径,但我认为它们实际上与SQL Server正在使用的递归路径相同,所以如果我有一种获取此递归路径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,但它是由“电平> 1”子句左出来的结果。

感谢,Steef

+2

结果究竟应该如何相似?你想得到两行结果和每个完整路径吗? –

+0

Hi Georg,我想要一个额外的列'path_id'追加 – Steef

+1

行,但是,然后,你需要输出ID为“101”TWICE,一次path_id“1”,一次path_id“2” –

回答

2

如果我理解正确的话,您正在寻找这样的事情。

数据

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; 
+0

嗨乔治,我在我的问题中添加了我想要的输出。 – Steef

+0

@Steef - '101'出现在两条路径中。你如何确定它应该出现在'path_id 1'而不是'path id 2'中 – ughai

+0

如果一个节点在2条路径中,应该使用第一条路径。路径2从节点104开始。 – Steef