繁体   English   中英

如何通过任何节点获取树(SQL)

[英]How to get tree by any node(SQL)

我有自引用表 - HIERARCHY(id, name, parent_id) 所以我需要通过这个层次结构的任何节点来获取所有层次结构。 例如,我们有树,其中h1h2是根:

-(h1)
  | |_(h1_1)
  | |   |_(h1_1_2)
  | |_(h1_2)
  |    |_(h1_2_1)
-(h2)
  | |_(h2_1)
  | |_(h2_2)   
  |     

我需要的是,它通过这棵树的任何节点(例如h1_2获取所有树,例如根h1

     -(h1)
        |_(h1_1)
get     |   |_(h1_1_2)    by h1_2 or h1_2_1, etc
        |_(h1_2)
           |_(h1_2_1)

我写了查询:

WITH RECURSIVE hierarchy_with_parents(id) AS (
  SELECT l.id, l.name, l.parent_id FROM hierarchy AS l WHERE l.id = <any_row_id>
  UNION ALL
  SELECT lc.id, lc.name, lc.parent_id FROM hierarchy lc, hierarchy_with_parents lwp WHERE lc.id = lwp.parent_id
), hierarchy_with_children(id) AS (
  SELECT l.id, l.name, l.parent_id FROM hierarchy AS l WHERE l.id 
  IN ( -- sub-query for getting parent id
    SELECT
    lwp.id
    FROM hierarchy_with_parents AS lwp
    WHERE lwp.parent_id IS NULL
  )
  UNION ALL
  SELECT lc.id, lc.name, lc.parent_id FROM hierarchy lc, hierarchy_with_children lwc WHERE lc.parent_id = lwc.id
)
SELECT * FROM hierarchy_with_children

hierarchy_with_parents - 将子树从子树返回到父树(包括),
hierarchy_with_children - 返回所有树。

似乎一切正常,但我不是数据库专家,我想知道关于我的查询的限制和评论。 也欢迎任何其他 PostgreSQL 和 Oracle 11g 解决方案。

谢谢。

给定:input_node ,首先找到包含该节点的子树的根。 这是在find_root分解子查询中完成的。 然后只需收集链接到该根的所有行。 我需要在外部查询中调用NVL() ,以防:input_node已经是根; 在这种情况下find_root返回任何行。 当用作标量子查询时,它被视为null (至少在 Oracle 中),因此我可以使用NVL()来修复它。

with
     hierarchy as (
       select 2 as child, 1  as parent from dual union all
       select 3, 2 from dual union all
       select 4, 1 from dual union all
       select 5, 4 from dual union all
       select 7, 6 from dual union all
       select 8, 7 from dual union all
       select 9, 6 from dual
     ),
     find_root as (
       select parent as rt
       from hierarchy
       where connect_by_isleaf = 1       
       start with child = :input_node
       connect by child = prior parent
     ) 
select child, parent
from   hierarchy
start with parent = nvl((select rt from find_root), :input_node)
connect by parent = prior child;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM