• 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也可以是任意的树节点,即查询以该节点为根的树)

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

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

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

    二、复杂的级联查询

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

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

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

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

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

    组织代码层级1层级2层级3
    111 公司1部门1小组1
    120公司1部门2
    211公司2部门3小组2
    220公司2部门4
    1. SELECT M_CODE,
    2. listagg(CASE NODE_LEVEL
    3. WHEN '1' THEN
    4. NODE_NAME
    5. ELSE
    6. ''
    7. END) within group(order by NODE_LEVEL ASC) AS L1,
    8. listagg(CASE NODE_LEVEL
    9. WHEN '2' THEN
    10. NODE_NAME
    11. ELSE
    12. ''
    13. END) within group(order by NODE_LEVEL ASC) AS L2,
    14. listagg(CASE NODE_LEVEL
    15. WHEN '3' THEN
    16. NODE_NAME
    17. ELSE
    18. ''
    19. END) within group(order by NODE_LEVEL ASC) AS L3
    20. FROM (select NODE_NAME, NODE_LEVEL, CONNECT_BY_ROOT(NODE_CODE) M_CODE
    21. from TREE t
    22. start with NODE_CODE in (select NODE_CODE
    23. from TREE t1
    24. WHERE IS_LEAF= '1' --叶子节点
    25. )
    26. connect by NODE_CODE = prior PARENT_ID)
    27. GROUP BY M_CODE

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

  • 相关阅读:
    Git命令总结-常用-后续使用频繁的再添加~
    docker使用Inbucket搭建邮件服务器用于接受邮件
    【产品设计】有了创意,如何从零开始搭建一套产品模型
    List 对象集合,如何优雅地返回给前端?
    Spring Data JPA系列5:让IDEA自动帮你写JPA实体定义代码
    Win11更新后瘦身C盘的两个小技巧
    string.format()
    【blood group + transferase】
    py15_Python 流程控制之 for-else 和 range() 步长以及 break/continue/return 跳转语句
    入门力扣自学笔记120 C++ (题目编号1417)
  • 原文地址:https://blog.csdn.net/ido1ok/article/details/126403967