一、语法

{ CONNECT BY [ NOCYCLE ] condition [AND condition]... [ START WITH condition ]
| START WITH condition CONNECT BY [ NOCYCLE ] condition [AND condition]...}

解释:

start with: 指定起始节点的条件

connect by: 指定父子行的条件关系

prior: 查询父行的限定符,格式: prior column1 = column2 or column1 = prior column2 and ... ,

nocycle: 若数据表中存在循环行,那么不添加此关键字会报错,添加关键字后,便不会报错,但循环的两行只会显示其中的第一条

循环行: 该行只有一个子行,而且子行又是该行的祖先行

connect_by_iscycle: 前置条件:在使用了nocycle之后才能使用此关键字,用于表示是否是循环行,0表示否,1 表示是

connect_by_isleaf: 是否是叶子节点,0表示否,1 表示是

level: level伪列,表示层级,值越小层级越高,level=1为层级最高节点


二、使用

oracle的start with connect by prior是根据条件递归查询"树",分为四种使用情况:

第一种:查询结果自己所有的后代节点(包括自己)

start with 子节点ID='...' connect by prior 子节点ID = 父节点ID


select * from mdm_organization o start with o.org_code='10000008' connect by prior o.org_code=o.org_parent_code

按照条件org_code='10000008',对'10000008'(包括自己)及其子节点进行递归查询,结果如下:

第二种:查询结果自己所有的前代节点(包括自己)

start with 子节点ID='...' connect by 子节点ID = prior 父节点ID


select * from mdm_organization o start with o.org_code='10000008' connect by o.org_code=prior o.org_parent_code

按照条件org_code='10000008',对'10000008'(包括自己)及其父节点进行递归查询,结果如下:

第三种:查询结果自己所有的后代节点(不包括自己)

start with 父节点ID='...' connect by prior 子节点ID = 父节点ID


select * from mdm_organization o start with o.org_parent_code='10000008' connect by prior o.org_code=o.org_parent_code

按照条件org_parent_code='10000008',对'10000008'(不包括自己)子节点进行递归查询,结果如下:

第四种:查询结果自己的第一代后节点和所有的前代节点(包括自己)

start with 父节点ID='...' connect by 子节点ID = prior 父节点ID


select * from mdm_organization o start with o.org_parent_code='10000008' connect by o.org_code = prior o.org_parent_cod

按照条件org_parent_code='10000008',对'10000008'(包括自己)的第一代孩子们及其父节点进行递归查询,结果如下:

如果有where 条件,如下:

select * from mdm_organization o where 条件 start with o.org_parent_code='10000008' connect by o.org_code = prior o.org_parent_code

执行顺序为先执行start with connect by prior,然后再按照where条件进行过滤。

该部分参考(oracle的start with connect by prior如何使用),具体请前往查看。

三、函数

1、sys_connect_by_path函数

语法:sys_connect_by_path(列名, '分隔符')。
作用:从start with的地方开始遍历,将遍历到的路径根据函数中的分隔符,组成一个新的字符串。

select sys_connect_by_path(ename, '/') ename_tree from scott.emp
 	start with ename = 'KING'
	connect by mgr = prior empno;

sys_connect_by_path函数使用的一个小技巧,把查询行转换成列,把表emp的所有列名以'|'分隔开输出(提示:大家可以把下面的语句拆开来逐个分析),SQL语句如下:

select max(ltrim(sys_connect_by_path(column_name, '|'), '|')) column_names from (select column_name, rownum rnum
          from user_tab_columns
         where table_name = 'EMP')
 start with rnum = 1
connect by rnum = rownum;

2、level函数

在结构化查询结果中,每一行都是结构中的一个节点,level表示该节点在结构中的层次,根节点为1,根节点的子节点为2,以此类推。
下面SQL语句很直观的展示效果:

select ename, sys_connect_by_path(ename, '/') ename_tree, level
  from scott.emp
 start with ename = 'KING'
connect by mgr = prior empno;

3、connect_by_root函数

用在列名之前,返回当前节点的根节点对应列的值。

下面SQL语句很直观的展示效果:

select connect_by_root ename as root
from scott.emp e
start with e.ename = 'KING'
connect by prior e.empno = e.mgr;

4、connect_by_isleaf函数

返回当前节点是否为叶子节点,“是”返回1,“否”返回0。

下面SQL语句很直观的展示效果:

select connect_by_isleaf as isleaf
from scott.emp e
start with e.ename = 'KING'
connect by prior e.empno = e.mgr;

该部分参考(Oracle高级查询之CONNECT BY),具体请前往查看。


随时用到,随时待续。。。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐