SQL递归记录:如何折叠到"仅一级"?

Jan*_*gen 3 sql sql-server oracle recursion firebird

我有一个带有项目ID和'inherit id'的记录,即当前项目继承的项目.继承级别未知.

我现在需要将其折叠为:'从最顶层继承'

例如:

1006 <- 1005 <- 1002 <- 999
Run Code Online (Sandbox Code Playgroud)

prj_id/inherit_id

999  / 1002

1002 / 1005

1005 / 1006
Run Code Online (Sandbox Code Playgroud)

应该崩溃到

1006 <- 1005 

1006 <- 1002

1006 <- 999
Run Code Online (Sandbox Code Playgroud)

prj_id/inherit_id

999  / 1006

1002 / 1006

1005 / 1006
Run Code Online (Sandbox Code Playgroud)

这可以在没有循环的SQL语句中完成吗?创建临时表很好.它适用于FireBird,SQL Server,Oracle 9+(即3套语句都可以)

我只有这么远:

从自身再次继承的记录继承的记录:

select tt_prj_id,tt_name,tt_inherit_id from tt_prj a

where a.tt_inherit_id in

(select tt_prj_id from tt_prj b

 where b.tt_inherit_id is not null

 and b.tt_inherit_id > 0)
Run Code Online (Sandbox Code Playgroud)

谁可以帮我进一步?

a_h*_*ame 6

像下面这样的东西应该让你开始(这不是最终的解决方案!):

with recursive project_tree as (
   select tt_prj_id, cast(tt_prj_id as varchar(500))||'/' as id_path, tt_prj_id as root_id
   from tt_prj
   where tt_inherit_id = 0

   union all

   select c.tt_prj_id, id_path || cast(c.tt_prj_id as varchar(100)) ||'/', null
   from tt_prj c
     join project_tree p on c.tt_inherit_id = p.tt_prj_id
)
select *
from project_tree;
Run Code Online (Sandbox Code Playgroud)

这适用于Firebird 2.5(可能也适用于2.1,但我现在手头没有)

当您删除关键字时,它应该与SQL Server一起使用recursive(这是ANSI标准所要求的,但是从那时起Microsoft是否关心...)并且您需要||+运算符替换标准字符串连接.

Oracle在11.2之前只支持递归CTE.在以前的版本中,你需要使用重写它CONNECT BY,这可能是这样的:

select tt_prj_id, tt_inherit_id, sys_connect_by_path(tt_prj_id, '/')
from tt_prj
start with tt_inherit_id = 0
connect by prior tt_prj_id = tt_inherit_id;
Run Code Online (Sandbox Code Playgroud)