我有一个带有项目ID和'inherit id'的记录,即当前项目继承的项目。继承级别未知。
我现在需要将其折叠为:'从最顶层继承'
E.g:
1006 <- 1005 <- 1002 <- 999
prj_id / inherit_id
999 / 1002
1002 / 1005
1005 / 1006
应该崩溃到
1006 <- 1005
1006 <- 1002
1006 <- 999
prj_id / inherit_id
999 / 1006
1002 / 1006
1005 / 1006
这可以在没有循环的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)
谁可以帮助我?
答案 0 :(得分: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;
这适用于Firebird 2.5(可能也适用于2.1,但我现在手头没有)
当你删除关键字recursive
(这是ANSI标准所要求的,但是从什么时候开始关心那个...)并且你需要替换标准字符串连接时,它应该与SQL Server一起使用{使用||
运算符{1}}。
Oracle在11.2之前只支持递归CTE。
在以前的版本中,您需要使用+
重写此内容,这可能是这样的:
CONNECT BY
答案 1 :(得分:1)
在transitive closure tables
或nested sets
上进行搜索。它们的结构使得有效查询关系数据成为可能,但它需要对插入/更新/删除进行更多维护,并且关闭表将需要存储额外的记录(权衡空间以提高效率)。
答案 2 :(得分:1)
用户a_horse_with_no_name是正确的。可以使用递归CTE执行此操作。查看此链接以获取更多信息。
http://blog.sqlauthority.com/2008/07/28/sql-server-simple-example-of-recursive-cte/
再一次,Pinal Dave ftw。