08.SQL基礎-->層次化查詢(START BY ... CONNECT BY PRIOR)
阿新 • • 發佈:2017-12-22
log ada body 偽列 過濾 exp image 遍歷 col
SQL基礎-->層次化查詢(START BY ... CONNECT BY PRIOR)
層次化查詢,即樹型結構查詢,是SQL中經常用到的功能之一,通常由根節點,父節點,子節點,葉節點組成,其語法如下:
SELECT [LEVEL] ,column,expression,... FROM table_name [WHERE where_clause] [[START WITH start_condition] [CONNECT BY PRIOR prior_condition]]; LEVEL:為偽列,用於表示樹的層次 start_condition:層次化查詢的起始條件
--使用start with ...connect by prior 從根節點開始遍歷
select empno,mgr,ename,job from emp start with empno = 7839 connect by prior empno = mgr;
樹型結構遍歷過程(通過上面的查詢來描述) 1).從根節點開始(即where_clause中的條件,如果為非根節點則分根節點作為根節點開始遍歷,如上例empno = 7839) 2).遍歷根節點(得到empno = 7839記錄的相關信息) 3).判斷該節點是否存在由子節點,如果則訪問最左側未被訪問的子節點,轉到),否則下一步 如上例中prior_condition為empno = mgr,即子節點的mgr等於父節點的empno,在此時mgr為7839的記錄 4).當節點為葉節點,則訪問完畢,否則,轉到) 5).返回到該節點的父節點,轉到) --偽列level的使用 --註意connect by prior empno = mgr 的理解 --prior表示前一條記錄,即下一條返回記錄的mgr應當等於前一條記錄的empno
select level,empno,mgr,ename,job from emp start with ename = ‘KING‘ connect by prior empno = mgr order by level;
--獲得層次數
select count(distinct level) "Level" from emp start with ename = ‘KING‘ connect by prior empno = mgr;
--格式化層次查詢結果(使用左填充* level - 1個空格)
col Ename for a30 selectlevel, lpad(‘ ‘,2 * level - 1) || ename as "Ename", job from emp start with ename = ‘KING‘ connect by prior empno = mgr;
--從非根節點開始遍歷(只需修改start with 中的條件即可)
select level, lpad(‘ ‘,2 * level - 1) || ename as "Ename", job from emp start with ename = ‘SCOTT‘ connect by prior empno = mgr;
--從下向上遍歷(交換connect by prior中的條件即可,使用mgr = empno) --註意connect by prior mgr = empno 的理解 --prior表示前一條記錄,即下一條返回記錄的empno應當等於前一條記錄的mgr
select level, lpad(‘ ‘,2 * level - 1) || ename as "Ename", job from emp start with ename = ‘SCOTT‘ connect by prior mgr = empno;
--從下向上遍歷(也可以將prior置於等號右邊,得到相同的結果)
select level, lpad(‘ ‘,2 * level - 1) || ename as "Ename", job from emp start with ename = ‘SCOTT‘ connect by empno = prior mgr;
--從層次查詢中刪除節點和分支
select level, lpad(‘ ‘,2 * level - 1) || ename as "Ename" ,job from emp where ename != ‘SCOTT‘ --通過where子句來過濾SCOTT用戶,但SCOTT的下屬ADAMS並沒有過濾掉 start with empno = 7839 connect by prior empno = mgr;
--通過將過濾條件由where 子句的內容移動到connect by prior 子句中過濾掉SCOTT及其下屬
select level, lpad(‘ ‘,2 * level - 1) || ename as "Ename" ,job from emp start with empno = 7839 connect by prior empno = mgr and ename != ‘SCOTT‘;
--在層次化查詢中增加過濾條件或使用子查詢
select level, lpad(‘ ‘,2 * level - 1) || ename as "Ename" ,job from emp where sal > 2500 start with empno = 7839 connect by prior empno = mgr;
select level, lpad(‘ ‘,2 * level - 1) || ename as "Ename" ,job from emp where sal > (select avg(sal) from emp) start with empno = 7839 connect by prior empno = mgr ;
08.SQL基礎-->層次化查詢(START BY ... CONNECT BY PRIOR)