ORACLE-SQL 关于树结构的查询

1、通常的树结构包括节点编码NODE_CODE,节点名称NODE_NAME,父节点编码PARENT_ID

2、另外还可以拥有一些控制字段,排序SORT_NO,节点层级NODE_LEVEL,是否显示IS_SHOW,是否叶子节点IS_LEAF

3、除此之外,偶尔包含:唯一标识ID,创建人REC_CREATOR,创建时间REC_CREATE_TIME,修改人REC_REVISOR,修改时间REC_REVISE_TIME

4、一般的,默认根节点ID为ROOT,即树展开第一层节点的父节点编码为root。数字1标识是,数字0标识否。

以下面数据表举例

IDNODE_CODENODE_NAMEPARENT_IDNODE_LEVELIS_SHOWIS_LEAFSORT_NO
1100公司1root1101
2110部门11002102
3111小组11103113
4120部门21002114
5200公司2root1105
6210部门32002106
7211小组22103117
8220部门42002118

一、简单的级联查询

1、从root到叶子 (root也可以是任意的树节点,即查询以该节点为根的树)

select NODE_CODE, NODE_NAME, PARENT_ID, NODE_LEVEL
  from TREE --具有子接点ID与父接点ID的表 
 start with PARENT_ID= 'root' --给定一个startid(字段名为子接点ID,及开始的ID号)
connect by prior NODE_CODE = PARENT_ID--联接条件为子接点等于父接点,不能反

2、从叶子到root(从小组2到公司2)

  select NODE_CODE,
         NODE_NAME,
         PARENT_ID,
         NODE_LEVEL 
   start with NODE_CODE = '211' --给定一个startid(字段名为子接点ID,及开始的ID号)
  connect by prior PARENT_ID= NODE_CODE --联接条件为子接点等于父接点,不能反

二、复杂的级联查询

1、查询 小组1的代码,以及级联的部门,公司信息(反之把desc换成asc)

111 小组1-部门1-公司1(反之把desc换成asc)
 select M_CODE,
        listagg(NODE_NAME, '-') within group(order by NODE_CODE desc) AS NAME
   from (select t.*, CONNECT_BY_ROOT(NODE_CODE) M_CODE
           from TREE t
          start with NODE_CODE = '111'
         connect by NODE_CODE = prior PARENT_ID
          order by NODE_CODE asc)
  group by M_CODE;

2、显示所有叶子节点,代码,以及级联的部门,公司信息(反之把desc换成asc)

111 小组1-部门1-公司1(反之把desc换成asc)
120部门2-公司1
211小组2-部门3-公司2
220部门4-公司2
select M_CODE,
        listagg(NODE_NAME, '-') within group(order by NODE_CODE ASC) AS NAME
       
  from (select t.*, CONNECT_BY_ROOT(NODE_CODE) M_CODE
          from TREE t
         start with NODE_CODE in (select NODE_CODE
                                    from TREE t1
                                   WHERE IS_LEAF= '1')
        connect by NODE_CODE = prior PARENT_ID
         order by NODE_CODE asc)
 group by M_CODE

三、根据层级展示树节点结构(适用于查询人员组织机构信息)

组织代码层级1层级2层级3
111 公司1部门1小组1
120公司1部门2
211公司2部门3小组2
220公司2部门4
SELECT M_CODE,
       listagg(CASE NODE_LEVEL
                 WHEN '1' THEN
                  NODE_NAME
                 ELSE
                  ''
               END) within group(order by NODE_LEVEL ASC) AS L1,
       listagg(CASE NODE_LEVEL
                 WHEN '2' THEN
                  NODE_NAME
                 ELSE
                  ''
               END) within group(order by NODE_LEVEL ASC) AS L2,
       listagg(CASE NODE_LEVEL
                 WHEN '3' THEN
                  NODE_NAME
                 ELSE
                  ''
               END) within group(order by NODE_LEVEL ASC) AS L3
  FROM (select NODE_NAME, NODE_LEVEL, CONNECT_BY_ROOT(NODE_CODE) M_CODE
          from TREE t
         start with NODE_CODE in (select NODE_CODE
                                    from TREE t1
                                   WHERE IS_LEAF= '1' --叶子节点
                                  )
        connect by NODE_CODE = prior PARENT_ID)
 GROUP BY M_CODE

1、场面有几个注意点:横表转竖表、对文字进行求和(listagg)

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值