如果表中存在层次数据,则可以使用层次化查询子句查询出表中行记录之间的层次关系
基本语法:
  START WITH <condition1> CONNECT BY [ NOCYCLE ] <condition2>
  注: [ NOCYCLE ]参数暂时不解释
例:

SQL> select empno, ename, job, mgr, hiredate, sal, comm, deptno, level as lv from emp
  2      start with empno = 7839 connect by (prior empno) = mgr;
EMPNO ENAME      JOB                              MGR HIREDATE          SAL      COMM DEPTNO         LV
----- ---------- ------------------------------ ----- ----------- --------- --------- ------ ----------
 7839 KING       PRESIDENT                            1981-11-17    5000.25               10          1
 7566 JONES      MANAGER                         7839 1981-04-02    2975.25               20          2
 7788 SCOTT      ANALYST                         7566 1982-12-09    3000.25               20          3
 7876 ADAMS      CLERK                           7788 1983-01-12    1100.25               20          4
 7902 FORD       ANALYST                         7566 1981-12-03    3000.25               20          3
 7369 SMITH      CLERK                           7902 1980-12-17     800.25               20          4
 7698 BLAKE      MANAGER                         7839 1981-05-01    2850.25               30          2
  120 gxl        SALESMAN                        7698 2018-02-08    5500.25    300.00     10          3
 7499 ALLEN      SALESMAN                        7698 1981-02-20    1600.25    300.00     30          3
 7521 WARD       SALESMAN                        7698 1981-02-22    1250.25    500.00     30          3
 7654 MARTIN     SALESMAN                        7698 1981-09-28    1250.25   1400.00     30          3
 7844 TURNER     SALESMAN                        7698 1981-09-08    1500.25      0.00     30          3
 7900 JAMES      CLERK                           7698 1981-12-03     950.25               30          3
 7782 CLARK      MANAGER                         7839 1981-06-09    2450.25               10          2
 7934 MILLER     CLERK                           7782 1982-01-23    1300.25               10          3
15 rows selected


表中存在层次数据
数据之间的层次关系即父子关系,通过表中列与列间的关系来描述,如EMP表中的EMPNO和MGR。EMPNO表示雇员编号,MGR表示领导
该雇员的人的编号,在表的每一行中都有一个表示父节点的MGR(除根节点外),通过每个节点的父节点,就可以确定整个树结构。
    
CONNECT BY [ NOCYCLE ] CONDITION2 层次子句作用
CONDITION2 [PRIOR expr = expr] : 指定层次结构中父节点与子节点之之间的关系。
CONDITION2 中的 一元运算符 PRIORY 必须放置在连接关系的两列中某一个的前面。在连接关系中,除了可以使用列名外,还允许使用列表达式。

1.START WITH
start with 子句为可选项,用来标识哪行作为查找树型结构的第一行(即根节点,可指定多个根节点)。若该子句被省略,则表示所有满足查询条件的行作为根节点。
2.关于PRIOR
PRIOR 置于运算符前后的位置,决定着查询时的检索顺序。
 
2.1 从根节点自顶向下
SQL> select empno, ename, mgr, level as lv from emp start with mgr is null
  2  connect by (prior empno) = mgr order by level;
EMPNO ENAME        MGR         LV
----- ---------- ----- ----------
 7839 KING                      1
 7566 JONES       7839          2
 7782 CLARK       7839          2
 7698 BLAKE       7839          2
 7902 FORD        7566          3
 7521 WARD        7698          3
 7788 SCOTT       7566          3
 7900 JAMES       7698          3
  120 gxl         7698          3
 7499 ALLEN       7698          3
 7934 MILLER      7782          3
 7654 MARTIN      7698          3
 7844 TURNER      7698          3
 7876 ADAMS       7788          4
 7369 SMITH       7902          4
15 rows selected

 

----分析
层次查询执行逻辑:
a. 确定上一行(相对于步骤b中的当前行),若start with 子句存在,则以该语句确定的行为上一行,若不存在则将所有的数据行视为上一行。
b. 从上一行出发,扫描除该行之外所有数据行。
c. 匹配条件 (prior empno) = mgr,注意 一元运算符 prior,意思是之前的,指上一行
当前行定义:步骤b中扫描得到的所有行中的某一行
匹配条件含义:当前行字段 mgr 的值等于上一行字段 empno中的值,若满足则取出该行,并将level + 1,
匹配完所有行记录后,将满足条件的行作为上一行,执行步骤 b,c。直到所有行匹配结束.

 
2.2 从根节点自底向上
SQL> select empno, ename, mgr, level as lv from emp start with empno = 7876
  2  connect by (prior mgr ) = empno order by level;
EMPNO ENAME        MGR         LV
----- ---------- ----- ----------
 7876 ADAMS       7788          1
 7788 SCOTT       7566          2
 7566 JONES       7839          3
 7839 KING                      4

--分析
层次查询执行逻辑:
a .确定上一行(相对于步骤b中的当前行),若start with 子句存在,则以该语句确定的行为上一行,若不存在则将所有的数据行视为上一行。
b .从上一行出发,扫描除该行之外所有数据行。
c .匹配条件 (prior mgr ) = empno
注意 一元运算符 prior,意思是之前的,指上一行
当前行定义:步骤b中扫描得到的所有行中的某一行
匹配条件含义:当前行字段 empno 的值等于上一行字段 mgr 中的值,若满足则取出该行,并将
level + 1
匹配完所有行记录后,将满足条件的行作为上一行,执行步骤 b,c。直到所有行匹配结束.

一、基本语法

SELECT * FROM TABLE START WITH <condition1> CONNECT BY [PRIOR] id= parentid;

层次查询(递归查询)用来查找存在父子关系的数据,也就是树形结构的数据;其返还的数据也能够明确的区分出每一层的数据。

"start  with <condition>"  --  代表在这棵树中你要开始遍历的的节点,是用来限制第一层的数据,或者叫根节点数据;以这部分数据

            为基础来查找第二层数据,然后以第二层数据查找第三层数据以此类推。

"connect  by  prior id = parentid"  --  标示节点之间的父子关系,是用来指明Oracle在查找数据时以怎样的一种关系去查找;比如说查

               找第二层的数据时用第一层数据的id去跟表里面记录的parentid字段进行匹配,如果这个条件成立

                那么查找出来的数据就是第二层数据,同理查找第三层第四层…等等都是按这样去匹配。

"level" -- 关键字,代表树形结构中的层级编号;第一层是数字1,第二层数字2,依次递增。

 prior还有一种用法:

select * from table [start with condition1] connect by id= [prior] parentid
或者:
select * from table [start with condition1] connect by [prior] parentid = id

二、分层查询的例子

1.从根节点查找叶子节点,即从根节点自顶向下

SQL> select level rn , empno,mgr,substr(sys_connect_by_path(ename,'-->'),4) from emp
  2  start with ename = 'KING' connect by prior empno = mgr;
        RN EMPNO   MGR SUBSTR(SYS_CONNECT_BY_PATH(ENA
---------- ----- ----- --------------------------------------------------------------------------------
         1  7839       KING
         2  7566  7839 KING-->JONES
         3  7788  7566 KING-->JONES-->SCOTT
         4  7876  7788 KING-->JONES-->SCOTT-->ADAMS
         3  7902  7566 KING-->JONES-->FORD
         4  7369  7902 KING-->JONES-->FORD-->SMITH
         2  7698  7839 KING-->BLAKE
         3   120  7698 KING-->BLAKE-->gxl
         3  7499  7698 KING-->BLAKE-->ALLEN
         3  7521  7698 KING-->BLAKE-->WARD
         3  7654  7698 KING-->BLAKE-->MARTIN
         3  7844  7698 KING-->BLAKE-->TURNER
         3  7900  7698 KING-->BLAKE-->JAMES
         2  7782  7839 KING-->CLARK
         3  7934  7782 KING-->CLARK-->MILLER
15 rows selected

2.从叶子节点查找上层节点

SQL> select level rn , empno, mgr, substr(sys_connect_by_path(ename,'-->'),4) tb from emp
  2  start with ename = 'ADAMS' connect by prior mgr = empno;
        RN EMPNO   MGR TB
---------- ----- ----- --------------------------------------------------------------------------------
         1  7876  7788 ADAMS
         2  7788  7566 ADAMS-->SCOTT
         3  7566  7839 ADAMS-->SCOTT-->JONES
         4  7839       ADAMS-->SCOTT-->JONES-->KING

 

 三、sys_connect_by_path 递归函数

 SYS_CONNECT_BY_PATH( cln, fmt )  :这个函数是oracle9i才新提出来的!它一定要和connect by子句合用!

        第一个参数cln是形成树形式的字段,第二个参数fmt是父级和其子级分隔显示用的分隔符,

        CONNECT BY PRIOR标示父子关系的对应!

 

 

SQL> SELECT level,empno,mgr,SYS_CONNECT_BY_PATH(ename, '>') pt
  2      FROM emp START WITH ename = 'KING' CONNECT BY PRIOR empno = mgr;
     LEVEL EMPNO   MGR PT
---------- ----- ----- --------------------------------------------------------------------------------
         1  7839       >KING
         2  7566  7839 >KING>JONES
         3  7788  7566 >KING>JONES>SCOTT
         4  7876  7788 >KING>JONES>SCOTT>ADAMS
         3  7902  7566 >KING>JONES>FORD
         4  7369  7902 >KING>JONES>FORD>SMITH
         2  7698  7839 >KING>BLAKE
         3   120  7698 >KING>BLAKE>gxl
         3  7499  7698 >KING>BLAKE>ALLEN
         3  7521  7698 >KING>BLAKE>WARD
         3  7654  7698 >KING>BLAKE>MARTIN
         3  7844  7698 >KING>BLAKE>TURNER
         3  7900  7698 >KING>BLAKE>JAMES
         2  7782  7839 >KING>CLARK
         3  7934  7782 >KING>CLARK>MILLER
15 rows selected

 

posted on 2018-07-22 12:27  WEDNESDAYOFNEO  阅读(534)  评论(0编辑  收藏  举报