加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Oracle层级询语句connect by 用法详解

发布时间:2020-12-12 13:30:18 所属栏目:百科 来源:网络整理
导读:如果表中包含层级数据,那么你就可以使用层级查询从句选择行层级顺序。 1.层级查询从句语法 层级查询从句语法: { CONNECT BY [ NOCYCLE ] condition [AND condition]... [ START WITH condition ] | START WITH condition CONNECT BY [ NOCYCLE ] condition

如果表中包含层级数据,那么你就可以使用层级查询从句选择行层级顺序。

1.层级查询从句语法

层级查询从句语法:

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

?

START WITH:指定层级的跟节点行。

CONNECT BY:指定层级的父行于子行的关系。

  • NOCYCLE参数指示Oracle数据库查询返回行,即使CONNECT BY在数据中存在循环。通常与CONNECT_BY_ISCYCLE伪列一起使用查看行是否包含循环。
  • 在层级查询中,表达式的条件必须使用PRIOR运算符加以限定来查询父行,例如:

???????? ... PRIOR expr = expr
???????? or
???????? ... expr = PRIOR expr

????? 如果CONNECT BY的条件是复合条件,只有一个条件PRIOR运算符是必须的,然而可以有多个PRIOR条件。例如:

????? CONNECT BY last_name != ‘King‘ AND PRIOR employee_id = manager_id ...
??????CONNECT BY PRIOR employee_id = manager_id and?
???????????????????????????? PRIOR account_mgr_id = customer_id ...

????? PRIOR是一个一元运算符和一元+-算术运算符具有相同的优先级。PRIOR根据层级查询中的表达式立刻计算出当前行的父行。

????? PRIOR必须与比较列值的相等运算符一起使用(PRIOD关键字可以相等运算符的任意一边)。

CONNECT BY条件和PRIOD表达两者之间形成一个不相关的子查询结构。因此CURRVAL和NEXTVAL是无效的PRIOR表达式,所以PRIOR表达不能用于查询序列。

通过使用CONNECT_BY_ROOT运算符来限定在查询列表中的列,可以进一步细化层级查询。这个运算符扩展了层级查询CONNECT BY [PRIOR]条件的功能,不仅立即返回父行,而且还返回层次结构中的所有行根节点行。

?

2.层级查询伪列

层级查询伪列只有在层级查询中是有效的,层级查询伪列:

2.1.CONNECT_BY_ISCYCLE伪列

如果当前行有一个子行,且子行又是当前行的祖先行,CONNECT_BY_ISCYCLE返回1,否则返回0.

只有在CONNECT BY从句中指定了NOCYCLE参数,才能指定CONNECT_BY_ISCYCLE。由于CONNECT BY存在循环数据,NOCYCLE能使Oracle返回查询结果,否则将查询失败。

2.2.CONNECT_BY_ISLEAF伪列

如果当前行是CONNECT BY条件定义树的叶子节点,CONNECT_BY_ISLEAF伪列返回1,否则返回0。该信息也表明了一个给定的行是否可以进一步扩张,表现出更多的层次。

2.3.LEVEL伪列

层级查询返回的每一行,跟节点行LEVEL伪列返回1,跟节点的子节点行LEVEL为例返回2等等。跟节点行是倒置树的最高行。子节点行是任意非跟节点行。父节点行是任意有子节点的行。叶子节点行是任意没有子节点行。

?

?

3.EXAMPLES

3.1.CONNECT BY Example

查询所有员工的上级。

?SQL> select e.empno,e.ename,e.mgr from emp e connect by prior e.empno = e.mgr;
?
EMPNO ENAME??????? MGR
----- ---------- -----
?7788 SCOTT?????? 7566
?7876 ADAMS?????? 7788
?7902 FORD??????? 7566
?7369 SMITH?????? 7902
?7499 ALLEN?????? 7698
?7900 JAMES?????? 7698
?7844 TURNER????? 7698
?7654 MARTIN????? 7698
?7521 WARD??????? 7698
?7934 MILLER????? 7782
?7876 ADAMS?????? 7788
?7566 JONES?????? 7839
?7788 SCOTT?????? 7566
?7876 ADAMS?????? 7788
?7902 FORD??????? 7566
?7369 SMITH?????? 7902

?........

?3.2.LEVEL Example

使用level虚列显示父行于子行的层级

SQL> select e.empno,e.mgr,level from emp e connect by prior e.empno = e.mgr;
?
EMPNO ENAME??????? MGR????? LEVEL
----- ---------- ----- ----------
?7788 SCOTT?????? 7566????????? 1
?7876 ADAMS?????? 7788????????? 2
?7902 FORD??????? 7566????????? 1
?7369 SMITH?????? 7902????????? 2
?7499 ALLEN?????? 7698????????? 1
?7900 JAMES?????? 7698????????? 1
?7844 TURNER????? 7698????????? 1
?7654 MARTIN????? 7698????????? 1
?7521 WARD??????? 7698????????? 1
?7934 MILLER????? 7782????????? 1
?7876 ADAMS?????? 7788????????? 1
?7566 JONES?????? 7839????????? 1
?7788 SCOTT?????? 7566????????? 2
?7876 ADAMS?????? 7788????????? 3
?7902 FORD??????? 7566????????? 2
?7369 SMITH?????? 7902????????? 3

............

?

3.3.START WITH Examples

从员工KING开始,查询出所有员工的上级

SQL> select e.empno,level
? 2??? from emp e
? 3? connect by prior e.empno = e.mgr
? 4?? start with e.ename = ‘KING‘;
?
EMPNO ENAME??????? MGR????? LEVEL
----- ---------- ----- ----------
?7839 KING????????????????????? 1
?7566 JONES?????? 7839????????? 2
?7788 SCOTT?????? 7566????????? 3
?7876 ADAMS?????? 7788????????? 4
?7902 FORD??????? 7566????????? 3
?7369 SMITH?????? 7902????????? 4
?7698 BLAKE?????? 7839????????? 2
?7499 ALLEN?????? 7698????????? 3
?7521 WARD??????? 7698????????? 3
?7654 MARTIN????? 7698????????? 3
?7844 TURNER????? 7698????????? 3
?7900 JAMES?????? 7698????????? 3
?7782 CLARK?????? 7839????????? 2
?7934 MILLER????? 7782????????? 3

?

3.4.NOCYCLE Examples

创建一个connect by 循环数据,将员工SCOTT指定为员工KING的上级,这样会就出现一个死循环。

创建循环数据:

SQL> update emp e set e.mgr = ‘7788‘ where e.ename = ‘KING‘;
?
查询以KING开始的员工的上级:

SQL> select e.empno,level
? 2??? from emp e
? 3? connect by prior e.empno = e.mgr
? 4?? start with e.ename = ‘KING‘;
?
select e.empno,level
? from emp e
connect by prior e.empno = e.mgr
?start with e.ename = ‘KING‘
?
ORA-01436: 用户数据中的 CONNECT BY 循环

?

使用NOCYCLE参数,查询以KING开始的员工上级:

SQL> select e.empno,level,connect_by_iscycle "CYCLE"? 2??? from emp e? 3? connect by nocycle prior e.empno = e.mgr? 4?? start with e.ename = ‘KING‘;?EMPNO ENAME??????? MGR????? LEVEL????? CYCLE----- ---------- ----- ---------- ----------?7839 KING??????? 7788????????? 1????????? 0?7566 JONES?????? 7839????????? 2????????? 0?7788 SCOTT?????? 7566????????? 3????????? 1?7876 ADAMS?????? 7788????????? 4????????? 0?7902 FORD??????? 7566????????? 3????????? 0?7369 SMITH?????? 7902????????? 4????????? 0?7698 BLAKE?????? 7839????????? 2????????? 0?7499 ALLEN?????? 7698????????? 3????????? 0?7521 WARD??????? 7698????????? 3????????? 0?7654 MARTIN????? 7698????????? 3????????? 0?7844 TURNER????? 7698????????? 3????????? 0?7900 JAMES?????? 7698????????? 3????????? 0?7782 CLARK?????? 7839????????? 2????????? 0?7934 MILLER????? 7782????????? 3????????? 0

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读