Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL递归循环_Sql_Sql Server - Fatal编程技术网

SQL递归循环

SQL递归循环,sql,sql-server,Sql,Sql Server,我的情况与非常类似,但关于添加FullID列的答案对我来说是不可能的 我有一个具有树层次结构的元素表树: ID NAME PARENT 1 a null 2 b null 3 c 1 4 d 3 5 e 2 6 f 4 7 g 3 我如何进行查询以返回这样的结果: a - c - d - f a - c - g b - e 我尝试使用WHILE循环,动态创建查询和临时表,但结果非常复杂,不起作

我的情况与非常类似,但关于添加FullID列的答案对我来说是不可能的

我有一个具有树层次结构的元素表树:

ID NAME PARENT
 1    a  null
 2    b  null
 3    c     1
 4    d     3
 5    e     2
 6    f     4
 7    g     3
我如何进行查询以返回这样的结果:

a - c - d - f
a - c - g
b - e

我尝试使用WHILE循环,动态创建查询和临时表,但结果非常复杂,不起作用。

您可以使用递归CTE获取所有分支。通用解决方案如下所示:

with
b as (
  select id, parent, cast(concat('', name) as varchar(255)) as branch 
  from t 
  where id not in (select parent from t where parent is not null)
union all
  select t.id, t.parent, cast(concat(t.name, ' - ', b.branch) as varchar(255))
  from b
  join t on t.id = b.parent
)
select id, branch from b where parent is null
结果:

branch       
-------------
a - c - g    
a - c - d - f
b - e        
作为参考,这是我使用的数据脚本:

create table t (
  id int,
  name varchar(6),
  parent int
);

insert into t (id, name, parent) values 
  (1, 'a', null),
  (2, 'b', null),
  (3, 'c', 1),
  (4, 'd', 3),
  (5, 'e', 2),
  (6, 'f', 4),
  (7, 'g', 3);

可以使用递归CTE获取所有分支。通用解决方案如下所示:

with
b as (
  select id, parent, cast(concat('', name) as varchar(255)) as branch 
  from t 
  where id not in (select parent from t where parent is not null)
union all
  select t.id, t.parent, cast(concat(t.name, ' - ', b.branch) as varchar(255))
  from b
  join t on t.id = b.parent
)
select id, branch from b where parent is null
结果:

branch       
-------------
a - c - g    
a - c - d - f
b - e        
作为参考,这是我使用的数据脚本:

create table t (
  id int,
  name varchar(6),
  parent int
);

insert into t (id, name, parent) values 
  (1, 'a', null),
  (2, 'b', null),
  (3, 'c', 1),
  (4, 'd', 3),
  (5, 'e', 2),
  (6, 'f', 4),
  (7, 'g', 3);

“结果非常复杂,不起作用。”-请说明您尝试了什么以及为什么不起作用,以避免读者重复任何错误。我无法在线发布代码,但我创建了一个临时表t0,插入了所有没有父项的条目,并循环创建新表,插入parent=t0.parent(如果i!=0,则插入t(i-1))的所有条目,然后另一个循环将所有创建的表连接在一起。“我无法在线发布代码”…为什么不?这不太可能是一个革命性的商业秘密……特别是如果它不起作用的话。如果它以某种方式包含敏感名称或其他内容,那么只需查找/替换它们即可。您的树示例非常特殊:它不分叉。如果
c
除了
d
之外还有一个额外的孩子
g
但是关于添加完整ID列的答案对我来说是不可能的
为什么?“结果非常复杂,不起作用。”-请说明您尝试了什么以及为什么不起作用,为了避免读者重复任何错误。我不能在线发布代码,但我创建了一个临时表t0,插入了所有没有父项的条目,并创建了一个循环来创建新表,插入parent=t0.parent(或t(I-1),如果I!=0),然后另一个循环将所有创建的表连接在一起。“我不能在线发布代码”为什么不呢?这不太可能是一个革命性的商业秘密……特别是如果它不起作用的话。如果它以某种方式包含敏感名称或其他内容,那么只需查找/替换它们即可。您的树示例非常特殊:它不分叉。如果
c
除了
d
之外还有一个额外的孩子
g
怎么办?
但是关于添加一个FullID列的答案对我来说是不可能的
为什么?虽然我发现递归CTE有时很有用,但我们必须记住MS SQL中的递归性是有限的,并且占用资源。根据OP的需要,他/她可以尝试基于XML的解决方案。虽然我发现递归CTE有时很有用,但我们必须记住MS SQL中的递归性是有限的,而且资源非常有限。根据OP的需要,他/她可以尝试基于XML的解决方案