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

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章