天天看点

oracle树状结构层级查询小结--connect by等

oracle树状结构层级查询小结--connect by等

一、简介:

(1)oracle树状结构查询即层次递归查询,是sql语句经常用到的。

(2)树状结构通常由根节点、父节点、子节点和叶节点组成,简单来说,一张表中存在两个字段,dept_id,par_dept_id,那么通过找到每一条记录的父级id即可形成一个树状结构,也就是par_dept_id=dept_id,通俗的说就是这条记录的par_dept_id是另外一条父级记录的dept_id,其树状结构层级查询的基本语法是:

  SELECT [LEVEL],*
  FEOM table_name 
  START WITH 条件1
  CONNECT BY PRIOR 条件2
  WHERE 条件3
  ORDER BY 排序字段;
           

说明:LEVEL---伪列,用于表示树的层次

     条件1---根节点的限定条件,当然也可以放宽权限,以获得多个根节点,也就是获取多个树

    条件2---连接条件,目的就是给出父子之间的关系是什么,根据这个关系进行递归查询

    条件3---过滤条件,对所有返回的记录进行过滤

     排序字段---对所有返回记录进行排序

(3)关键字解析:

1)start with 子句:遍历起始条件,如果要查父节点,这里可以用子结点的列,如果要查子节点,这里可以用父节点的列。

2)connect by 子句:连接条件。

3)prior:

要的时候有两种写法:connect by prior dept_id=par_dept_id 或 connect by dept_id=prior par_dept_id,

前一种写法表示采用自上而下的搜索方式(先找父节点然后找子节点),

后一种写法表示采用自下而上的搜索方式(先找叶子节点然后找父节点)。 

也可以这样理解:

prior跟父节点列parentid放在一起,就是往父结点方向遍历;

prior跟子结点列subid放在一起,则往叶子结点方向遍历;

 parentid、subid两列谁放在“=”前都无所谓,关键是prior跟谁在一起。

4)order by 子句:排序

二、实战解析,测试数据

博客地址:oracle树状结构层级查询小结之测试数据 https://blog.csdn.net/dboy_willow/article/details/81630485

三、测试数据查询(部分数据)

select * from SYS_DEPT;
           
oracle树状结构层级查询小结--connect by等

四、实战演示

在这张表中有三个字段:

部门主键id:dept_id ;     部门名称:dept_name  ;    部门编码:dept_code ;      父级部门id(首级部门为 -1): par_dept_id;

1.connect by level 取连续数值

select level from dual t connect by level < = 5;
           
oracle树状结构层级查询小结--connect by等

2.当前节点遍历子节点(遍历当前部门下所有子部门包括本身)

select t.dept_id, t.dept_name, t.dept_code, t.par_dept_id, level
  from SYS_DEPT t
 start with t.dept_id = '40288ac45a3c1e8b015a3c28b4ae01d6'
connect by prior t.dept_id = t.par_dept_id
 order by level, t.dept_code;
           

结果:dept_id=40288ac45a3c1e8b015a3c28b4ae01d6 是客运部主键,对其下的所有子部门进行遍历;

同时用  order by level,dept_code 进行排序 以便达到实际生活中想要的数据;共31条数据,部分数据如图所示:

oracle树状结构层级查询小结--connect by等

2.当前节点遍历子节点(遍历当前部门下部分子部门):在上面的数据中获取层级在3,也就是level=3的所有子部门。

select t.dept_id, t.dept_name, t.dept_code, t.par_dept_id, level
  from SYS_DEPT t
 where level = '3'
 start with t.dept_id = '40288ac45a3c1e8b015a3c28b4ae01d6'
connect by prior t.dept_id = t.par_dept_id
 order by level, t.dept_code;
           
oracle树状结构层级查询小结--connect by等

3.当前节点遍历父节点(遍历当前部门上面所有父级部门)

select t.dept_id, t.dept_name, t.dept_code, t.par_dept_id, level
  from SYS_DEPT t
 start with t.dept_id = '4028e4d35b5ca4ee015b6138b84b2e68'
connect by prior t.par_dept_id = t.dept_id
 order by level, t.dept_code;
           
oracle树状结构层级查询小结--connect by等

4.sys_connect_by_path函数:求父节点到子节点路径

简单介绍下,在oracle中sys_connect_by_path与connect by 一起使用,也就是先要有或建立一棵树,否则无用还会报错;

它的主要作用体现在path上即路径,是可以把个父节点下的所有节点通过某个字符区分,然后链接在一个列中显示;

sys_connect_by_path(column,clear),其中column是字符型或能自动转换成字符型的列名;

它的主要目的就是将父节点到当前节点的“path”按照指定的模式出现;

char可以是单字符也可以是多字符,但不能使用列值中包含的字符;

而且这个参数必须是常量,且不允许使用绑定变量,clear不要用逗号。

select ltrim(sys_connect_by_path(t.dept_name, '-->'), '-->'),
       t.dept_id,
       t.dept_name,
       t.dept_code,
       t.par_dept_id,
       level
  from SYS_DEPT t
 start with t.dept_id = '40288ac45a3c1e8b015a3c28b4ae01d6'
connect by prior t.dept_id = t.par_dept_id
 order by level, t.dept_code;
           
oracle树状结构层级查询小结--connect by等

备注:在他人博客基础上进行的改进和分析。