zoukankan      html  css  js  c++  java
  • ORACLE 的CONNECT BY、START WITH,CONNECT_BY_ROOT、CONNECT_BY_ISLEAF、SYS_CONNECT_BY_PATH,LEVEL的使用(Hierarchical query-层次查询)

    如果表中存在层次数据,则可以使用层次化查询子句查询出表中行记录之间的层次关系
    基本语法:
      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
  • 相关阅读:
    Swing 顶层容器
    创建第一个界面程序
    SWING
    通俗解释高中生能听懂的SVM本质和原理
    [初学者入门]任何机器学习套路?逻辑回归是什么?要有哪些未知参数待求解?如何优化?梯度下降是什么?如何用梯度下降
    贝叶斯公式在机器学习中有什么用,实例讲解Python实现朴素贝叶斯分类器
    通俗易懂适合初学者的机器学习实战(1):k- Nearest Neighbor (k个最近的邻居)KNN算法
    Python从0开始实现Numpy矩阵库,拒绝掉包侠,学习造轮子
    99%的人都会忽略的Python易错点总结
    遇到问题,有哪些有效的分析方法?
  • 原文地址:https://www.cnblogs.com/yiming523/p/9349696.html
Copyright © 2011-2022 走看看