若是表中包含層級數據,那麼你就可使用層級查詢從句選擇行層級順序。數據庫
層級查詢從句語法: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
... 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]條件的功能,不只當即返回父行,並且還返回層次結構中的全部行根節點行。
層級查詢僞列只有在層級查詢中是有效的,層級查詢僞列:
若是當前行有一個子行,且子行又是當前行的祖先行,CONNECT_BY_ISCYCLE返回1,不然返回0.
只有在CONNECT BY從句中指定了NOCYCLE參數,才能指定CONNECT_BY_ISCYCLE。因爲CONNECT BY存在循環數據,NOCYCLE能使Oracle返回查詢結果,不然將查詢失敗。
若是當前行是CONNECT BY條件定義樹的葉子節點,CONNECT_BY_ISLEAF僞列返回1,不然返回0。該信息也代表了一個給定的行是否能夠進一步擴張,表現出更多的層次。
層級查詢返回的每一行,跟節點行LEVEL僞列返回1,跟節點的子節點行LEVEL爲例返回2等等。跟節點行是倒置樹的最高行。子節點行是任意非跟節點行。父節點行是任意有子節點的行。葉子節點行是任意沒有子節點行。
查詢全部員工的上級。
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
........
使用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
............
從員工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
建立一個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