Oracle層級詢語句connect by 用法詳解

若是表中包含層級數據,那麼你就可使用層級查詢從句選擇行層級順序。數據庫

1.層級查詢從句語法

層級查詢從句語法:blog

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

 

START WITH:指定層級的跟節點行。io

CONNECT BY:指定層級的父行於子行的關係。ast

  • NOCYCLE參數指示Oracle數據庫查詢返回行,即便CONNECT BY在數據中存在循環。一般與CONNECT_BY_ISCYCLE僞列一塊兒使用查看行是否包含循環。
  • 在層級查詢中,表達式的條件必須使用PRIOR運算符加以限定來查詢父行,例如:

         ... PRIOR expr = expr
         or
         ... expr = PRIOR expr擴展

      若是CONNECT BY的條件是複合條件,只有一個條件PRIOR運算符是必須的,然而能夠有多個PRIOR條件。例如:date

      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 ...select

      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.ename, 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, e.ename, e.mgr, 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, e.ename, e.mgr, level
  2    from emp e
  3  connect by prior e.empno = e.mgr
  4   start with e.ename = 'KING';
 
select e.empno, e.ename, e.mgr, 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, e.ename, e.mgr, 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

相關文章
相關標籤/搜索