Oracle层次查询技巧

2014-11-24 18:34:58 · 作者: · 浏览: 0

create table emp_hire as


selectempno,mgr,ename from emp


select * from emp_hire



这些数据存在着层次关系


select


lpad('*',level,'*')||e.ename ename,


e.empno,


mgr fa_id,


(select ename from emp_hire where empno=e.mgr) fa_name


from emp_hiree


START WITH MGR IS NULL


CONNECT BY PRIOR EMPNO = MGR




层次是一棵树, 又如同一个家族图谱



每一个子节电只有一个父节点;


每一个分支,最末端是叶节点;



SELECT


ename Employee,


CONNECT_BY_ISLEAF IsLeaf,


LEVEL lev,


SYS_CONNECT_BY_PATH(ename, '/') Path


FROM emp


START WITH MGR IS NULL


CONNECT BY PRIOR EMPNO = MGR






检查一个层次是否存在闭循环


CONNECT_BY_ISCYCLE



找出根节点


CONNECT_BY_ROOT



SELECT


ename Employee,


CONNECT_BY_ISCYCLE,


CONNECT_BY_ROOT ename


FROM emp


START WITH MGR IS NULL


CONNECT BY NOCYCLE PRIOR EMPNO = MGR




层次查询的过滤条件


SELECT


ename Employee,


CONNECT_BY_ISLEAF IsLeaf,


LEVEL lev,


SYS_CONNECT_BY_PATH(ename, '/') Path


FROM emp


where level<3


START WITH MGR IS NULL


CONNECT BY PRIOR EMPNO = MGR



Restriction on LEVEL in WHERE Clauses In a [NOT] IN condition in a WHERE clause, if the right-hand side of the condition is asubquery, you cannot use LEVEL on the left-hand sideof the condition. However, you can specify LEVEL in a subquery of the FROM clause to achieve the same result. For example, thefollowing statement is not valid:



SELECT employee_id, last_name FROM employees


WHERE (employee_id,LEVEL)


IN (SELECTemployee_id, 2 FROM employees)


START WITHemployee_id = 2


CONNECT BY PRIORemployee_id = manager_id;


But the following statement is valid because it encapsulates the querycontaining the


LEVEL information in the FROM clause:



SELECT v.employee_id, v.last_name, v.lev


FROM


(SELECT employee_id,last_name, LEVEL lev


FROM employees v


START WITHemployee_id = 100


CONNECT BY PRIORemployee_id = manager_id) v


WHERE(v.employee_id, v.lev) IN


(SELECT employee_id,2 FROM employees);





SIBLINGS的排序



SELECT


ename Employee,


CONNECT_BY_ISLEAF IsLeaf,


LEVEL lev,


SYS_CONNECT_BY_PATH(ename, '/') Path


FROM emp


START WITH MGR IS NULL


CONNECT BY PRIOR EMPNO = MGR


ORDER SIBLINGS BY ename desc



注意:ORDER SIBLINGS By一定与start with 与 connect by一起使用