欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Oracle Connect By Prior

程序员文章站 2022-03-01 20:21:39
...
/**
*
connect by主要用于父子,祖孙,上下级等层级关系的查询
{ CONNECT BY [ NOCYCLE ] condition [AND condition]... [ START WITH condition ]
| START WITH condition CONNECT BY [ NOCYCLE ] condition [AND condition]...}
解释:
start with: 指定起始节点的条件
connect by: 指定父子行的条件关系
--PIROR ID = PARENT_ID,我是这样理解的,当前条(也是上一条)的ID等于下一条的PARENT ID。
prior: 查询父行的限定符,格式: prior column1 = column2 or column1 = prior column2 and ...(prior指上一行的指定字段值等于当前行的指定字段值)
nocycle: 若数据表中存在循环行,那么不添加此关键字会报错,添加关键字后,便不会报错,但循环的两行只会显示其中的第一条
循环行: 该行只有一个子行,而且子行又是该行的祖先行
connect_by_iscycle: 前置条件:在使用了nocycle之后才能使用此关键字,用于表示是否是循环行,0表示否,1 表示是
connect_by_isleaf: 是否是叶子节点,0表示否,1 表示是
level: level伪列,表示层级,值越小层级越高,level=1为层级最高节点
*/

--1.创建表
drop table employee;
create table employee(
       emp_id number(18),
       lead_id number(18),
       emp_name varchar2(200),
       salary number(10,2),
       dept_no varchar2(8)
);

-- 添加数据
insert into employee values('1',0,'king','1000000.00','001');
insert into employee values('2',1,'jack','50500.00','002');
insert into employee values('3',1,'arise','60000.00','003');
insert into employee values('4',2,'scott','30000.00','002');
insert into employee values('5',2,'tiger','25000.00','002');
insert into employee values('6',3,'wudde','23000.00','003');
insert into employee values('7',3,'joker','21000.00','003');
commit;

--查询以emp_id为0开始的节点的所有直属节点
SELECT
    emp_id,
    lead_id,
    emp_name,
    PRIOR emp_name AS lead_name,
    salary
FROM
    employee
START WITH
    lead_id = 0
CONNECT BY
    PRIOR emp_id = lead_id;
/**
level伪列的使用,格式化层级
connect_by_root 查找根节点
connect_by_isleaf 是否是叶子节点
SYS_CONNECT_BY_PATH 层次结构显示
*/
SELECT
    CONNECT_BY_ROOT(emp_name) root_emp_name,
    CONNECT_BY_ROOT(emp_id) root_emp_id,
    SYS_CONNECT_BY_PATH(emp_name, '/'),--层次结构显示
    lpad(
        ' ', level * 2, ' '
    )
    || emp_name AS emp_name,
    lead_id,
    salary,
    CONNECT_BY_ISLEAF
FROM
    employee
WHERE
    dept_no = '002'
START WITH
    lead_id = 1
CONNECT BY NOCYCLE
    PRIOR emp_id = lead_id;
--插入一条数据,与另一条emp_id=7的数据组成循环行
insert into employee values('3',7,'joker_cycle','21000.00','003');
commit;
-- connect_by_iscycle("CYCLE"), connect by nocycle
--若数据表中存在循环行,那么不添加此关键字会报错,添加关键字后,便不会报错,但循环的两行只会显示其中的第一条
SELECT
    emp_id,
    emp_name,
    lead_id,
    salary,
    CONNECT_BY_ISCYCLE AS cycle
FROM
    employee 
start with lead_id=0 CONNECT BY NOCYCLE
    PRIOR emp_id = lead_id;