Oracle中connect by level以及start with的使用

文章引用 http://www.360doc.com/content/13/0422/16/11947209_280153192.shtml

ORACLE--Connect By、Level、Start With的使用(Hierarchical query-层次查询)

Syntax 1 CONNECT BY [NOCYCLE] <condition> START WITH <condition>
Syntax 2 START WITH <condition> CONNECT BY [NOCYCLE] <condition>

参考网址:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:489772591421

            http://psoug.org/reference/connectby.html

            http://www.oradev.com/connect_by.jsp

           http://philip.greenspun.com/sql/trees.html
查找员工编号为7369的领导:

1 SELECT LEVEL,E.* FROM EMP E CONNECT BY PRIOR E.MGR = E.EMPNO  START WITH E.EMPNO = 7876
2 ORDER BY LEVEL DESC

"start with" -- this identifies all LEVEL=1 nodes in the tree

"connect by" -- describes how to walk from the parent nodes above to their children and 
their childrens children.

Easiest to use an example on emp. If we start with "where mgr is NULL", we generate the 
set of employees that have no mgr (they are the top of the tree). If we

CONNECT BY PRIOR EMPNO = /* current */ MGR

that will take all of the PRIOR records (the start with at first) and find all records 
such that the MGR column equals their EMPNO (find all the records of people managed by 
the people we started with).


使用WITH语句优化查询结果:优化等级

复制代码
 1 WITH A AS
 2  (SELECT MAX(LEVEL) + 1 LVL
 3     FROM EMP E
 4   CONNECT BY PRIOR E.MGR = E.EMPNO
 5    START WITH E.EMPNO = 7876
 6    ORDER BY LEVEL DESC)
 7 SELECT A.LVL 最高等级加1,
 8        LEVEL 当前等级,
 9        A.LVL - LEVEL 优化后等级,
10        E.*  FROM A,
11        EMP E CONNECT BY PRIOR E.MGR = E.EMPNO START WITH E.EMPNO = 7876 ORDER BY LEVEL DESC
复制代码

查找员工编号为7839的所有下属(7839为king):

1 SELECT LEVEL 等级, E.*
2   FROM EMP E
3 CONNECT BY PRIOR E.EMPNO = E.MGR
4  START WITH E.EMPNO = 7839

--构造整个的层次结构

1 select lpad(' ',level*2,' ')||ename ename, empno, mgr
2     from emp
3     START WITH MGR IS NULL
4     CONNECT BY PRIOR EMPNO = MGR

So, KING is the start with set then JONES BLAKE and CLARK fall under him. Each of them 
becomes the PRIOR record in turn and their trees are expanded.



使用Connect By 结合 level构造虚拟行:

1 SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5

使用rownum实现类似的功能:

1 SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5

---------------------待续-----------------------

使用UNION ALL构造两层节点的树:

视图如下所示:

复制代码
 1 CREATE OR REPLACE VIEW TREE_VIEW AS
 2 SELECT
 3  '1' AS rootnodeid,
 4  'xxxx有限责任公司' AS treename,
 5  '-1'  AS parent_id
 6 FROM dual
 7 UNION
 8 SELECT
 9   to_char(d.deptno),
10   d.dname || '_' ||d.loc,
11   '1' AS parent_id
12  FROM dept d;
复制代码

查询语句:

1 SELECT T.*, LEVEL
2   FROM TREE_VIEW T
3  START WITH T.PARENT_ID = '-1'
4 CONNECT BY PRIOR T.ROOTNODEID = T.PARENT_ID

-----以下为更新内容:

1、先查看总共有几个等级:

1 SELECT COUNT(LEVEL)
2   FROM EMP E
3 CONNECT BY PRIOR E.EMPNO = E.MGR
4  START WITH E.MGR IS NULL;

2、查看每个等级的人数。主要是通过LEVEL进行GROUP BY

1 SELECT COUNT(LEVEL)
2   FROM EMP E
3 CONNECT BY PRIOR E.EMPNO = E.MGR
4  START WITH E.MGR IS NULL
5  GROUP BY LEVEL;

3、Oracle 10g提供了一个简单的connect_by_isleaf=1,

0 表示非叶子节点

1 SELECT LEVEL AS 等级, CONNECT_BY_ISLEAF AS 是否是叶子节点, E.*
2   FROM EMP E
3 CONNECT BY PRIOR E.EMPNO = E.MGR
4  START WITH E.MGR IS NULL

4、SYS_CONNECT_BY_PATH

Oracle 9i提供了sys_connect_by_path(column,char),其中column 是字符型或能自动转

换成字符型的列名。它的主要目的就是将父节点到当前节点的”path”按照指定的模式展现出现。这个函数只能使用在层次查询中。

1 SELECT LEVEL AS 等级,
2        CONNECT_BY_ISLEAF AS 是否是叶子节点,
3        LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>')
4   FROM EMP E
5 CONNECT BY PRIOR E.EMPNO = E.MGR
6  START WITH E.MGR IS NULL;

5、修剪树枝和节点:

    过滤掉编号是7566的数据(修剪节点),他指的是把这个节点给裁掉,但是并没有破坏树结构,它的子节点还是可以正常的显示。

复制代码
1 SELECT LEVEL AS 等级,
2        CONNECT_BY_ISLEAF AS 是否是叶子节点,
3        LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'),
4        E.*
5   FROM EMP E
6 WHERE e.empno != 7566
7 CONNECT BY PRIOR E.EMPNO = E.MGR
8  START WITH E.MGR IS NULL;
复制代码

裁掉编号是7698的节点和它的子节点:

复制代码
1 SELECT LEVEL AS 等级,
2        CONNECT_BY_ISLEAF AS 是否是叶子节点,
3        LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'),
4        E.*
5   FROM EMP E
6 CONNECT BY PRIOR E.EMPNO = E.MGR
7        AND E.EMPNO != 7698
8  START WITH E.MGR IS NULL;
复制代码

6、CONNECT_BY_ROOT的使用,oracle10g新增connect_by_root,用在列名之前表示此行的根节点的相同列名的值。

复制代码
1 SELECT LEVEL AS 等级,
2        CONNECT_BY_ISLEAF AS 是否是叶子节点,
3        CONNECT_BY_ROOT ENAME,
4        LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'),
5        E.*
6   FROM EMP E
7 CONNECT BY PRIOR E.EMPNO = E.MGR
8  START WITH E.MGR IS NULL;
复制代码

 

对于层次查询如果用order by排序,比如order by last_name则是先做完层次获得level,然后按last_name 排序,这样破坏了层次,比如特别关注某行的深度,按level 排序,也是会破坏层次的。在oracle10g中,增加了siblings 关键字的排序。

语法:order siblings by <expre>

它会保护层次,并且在每个等级中按expre排序。

复制代码
1 SELECT LEVEL AS 等级,
2        CONNECT_BY_ISLEAF AS 是否是叶子节点,
3        LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'),
4        E.*
5   FROM EMP E
6 CONNECT BY PRIOR E.EMPNO = E.MGR 
7  START WITH E.MGR IS NULL
8  ORDER SIBLINGS BY  E.ENAME;
复制代码

connect_by_iscycle(存在循环,将返回1,否则返回0)

The CONNECT_BY_ISCYCLE pseudocolumn returns 1 if the current row has a child which is also its ancestor. Otherwise it returns 0. 
You can specify CONNECT_BY_ISCYCLE only if you have specified the NOCYCLE parameter of the CONNECT BY clause. NOCYCLE enables Oracle to return the results of a query that would otherwise fail because of a CONNECT BY loop in the data.

I believe that we are who we choose to be. Nobody‘s going to come and save you, you‘ve got to save yourself. 我相信我们成为怎样的人是我们自己的选择。没有人会来拯救你,你必须要自己拯救自己。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"Connect by prior" 是一种在 Oracle 数据库用于处理层次结构数据的关键字。它可以通过一个 SELECT 语句来实现对数据进行树形结构的查询和遍历。下面是一个详细的用例: 假设我们有一个表格 department,其包含了公司的各个部门信息,每个部门都有一个上级部门。表格结构如下: ``` DEPARTMENT_ID DEPARTMENT_NAME PARENT_DEPARTMENT_ID 1 CEO Office NULL 2 HR Department 1 3 Finance Department 1 4 IT Department 1 5 Marketing 1 6 Recruitment 2 7 Training 2 8 Payroll 3 9 Accounts Payable 3 ``` 我们希望查询出所有部门的层次结构,并按照层次结构进行排序,输出结果如下: ``` DEPARTMENT_ID DEPARTMENT_NAME LEVEL 1 CEO Office 1 2 HR Department 2 6 Recruitment 3 7 Training 3 3 Finance Department 2 8 Payroll 3 9 Accounts Payable 3 4 IT Department 2 5 Marketing 2 ``` 我们可以使用以下 SQL 语句来实现这个查询: ``` SELECT department_id, department_name, LEVEL FROM department START WITH parent_department_id IS NULL CONNECT BY PRIOR department_id = parent_department_id ORDER SIBLINGS BY department_name; ``` 解释一下这个语句的含义: - START WITH:指定查询的起始点,这里是 parent_department_id IS NULL,即根节点为 CEO Office。 - CONNECT BY PRIOR:指定层次关系的连接条件,这里是 department_id = parent_department_id,表示当前行的 department_id 列等于上一层行的 parent_department_id 列。 - ORDER SIBLINGS BY:按照同一级别的兄弟节点进行排序,这里是按照 department_name 进行排序。 最终的查询结果,每一行包含了当前部门的 department_id、department_name,以及它在层次结构LEVEL(层级)信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值