【问题标题】:SQL recursive loopSQL递归循环
【发布时间】:2020-01-10 12:40:25
【问题描述】:

我的情况与MySql sql recursive loop 非常相似,但我无法回答关于添加 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 循环,动态创建查询和临时表,但最终变得相当复杂并且没有用。

【问题讨论】:

  • "它最终变得相当复杂并且没有奏效。" - 请说明您尝试了什么以及为什么 它没有工作,以避免读者重复任何错误。
  • 我不能在线发布代码,但是我做了一个临时表t0,插入了所有没有父项的条目,并循环创建了新表,插入了所有父项= t0.parent(或 t(i-1) 如果 i != 0),然后另一个循环将所有创建的表连接在一起。
  • “我无法在线发布代码”...为什么不呢?它不太可能成为革命性的商业秘密……尤其是在它不起作用的情况下。如果它以某种方式包含敏感名称或其他内容,则只需为此目的查找/替换它们。
  • 您的树示例非常特别:它不会分叉。如果c 除了d 之外还有一个孩子g 怎么办?
  • but the answer about adding a FullID column wouldn't be possible for me 为什么?

标签: sql sql-server


【解决方案1】:

您可以使用递归 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 很有用,但我们必须牢记 MS SQL 中的递归是有限的并且资源占用很大。根据 OP 的需要,他/她可以尝试基于 XML 的解决方案
猜你喜欢
  • 1970-01-01
  • 2012-06-22
  • 2020-02-08
  • 1970-01-01
  • 2018-06-27
  • 2017-01-21
  • 2017-05-25
  • 2019-10-26
  • 1970-01-01
相关资源
最近更新 更多