嗯,我想我以前一直在做这样的事情。那时我有一个层次结构,问题是“找到节点 X 的所有子孙”。这在关系数据库中不是很容易做到 - 所以我制作了一个帮助表和一些脚本来填充它。让我们看看我是否能记住它……注意:这是在我记忆之后自由进行的,未经测试,不保证我做对了。我的问题也与您的问题有些不同,所以我不确定该解决方案是否适用。
create table chain_helper (
head int,
tail int,
chain_length int
)
create index chain_helper_by_head(head);
create index chain_helper_by_tail(tail);
这个想法是让这个表包含所有可能的链接,头和尾是外键。我的情况要容易一些,因为我有严格的层次结构,不需要循环控制。源表有一个 id 和一个 parent_id 字段。这是我填充表格的方式:
使用简单链接初始化表:
insert into chain_helper (head, tail, chain_length)
select id, parent_id, 1 from source_table;
我继续用所有长度为 2 的链填充表格:
insert into chain_helper (head, tail, chain_length)
select parent.head, child.tail, min(parent.chain_length + 1)
from chain_helper parent
join source_table child on source_table.parent_id=parent.id
where not exists
(select * from chain_helper where head=parent.head and tail=child.tail)
group by parent.head, child.tail;
(因为我有一个严格的层次结构,我不需要聚合 - 在我的情况下不会有重复)。
重复将插入所有长度为 3 的链,以此类推,并且该语句可以全部重复,直到没有更多内容可插入。然后找到最大链长度很简单:
select max(chain_length) from chain_helper;
这个解决方案并不容易显示链 - 但在我的情况下这不是必需的。我主要在连接中使用 chain_helper 以便能够捕获层次结构中特定节点的所有子节点和孙子节点 - 即“此子树的总收入”:
select sum(source_table.revenue)
from source_table join chain_helper on chain_helper.tail = source_table.id
where chain_helper.head = parent_of_subtree;