ORACLE--Connect By、Level、Start With的使用(Hierarchical query-層次查詢)
參考網(wǎng)址:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:489772591421 http:///reference/connectby.html http://philip./sql/trees.html 1 SELECT LEVEL,E.* FROM EMP E CONNECT BY PRIOR E.MGR = E.EMPNO START WITH E.EMPNO = 7876 "start with" -- this identifies all LEVEL=1 nodes in the tree "connect by" -- describes how to walk from the parent nodes above to their children and Easiest to use an example on emp. If we start with "where mgr is NULL", we generate the CONNECT BY PRIOR EMPNO = /* current */ MGR that will take all of the PRIOR records (the start with at first) and find all records
1 WITH A AS 查找員工編號(hào)為7839的所有下屬(7839為king): 1 SELECT LEVEL 等級(jí), E.* --構(gòu)造整個(gè)的層次結(jié)構(gòu) 1 select lpad(' ',level*2,' ')||ename ename, empno, mgr So, KING is the start with set then JONES BLAKE and CLARK fall under him. Each of them 使用Connect By 結(jié)合 level構(gòu)造虛擬行: 1 SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5 使用rownum實(shí)現(xiàn)類似的功能: 1 SELECT LEVEL FROM DUAL CONNECT BY LEVEL < 5 ---------------------待續(xù)----------------------- 使用UNION ALL構(gòu)造兩層節(jié)點(diǎn)的樹(shù): 視圖如下所示: 1 CREATE OR REPLACE VIEW TREE_VIEW AS 查詢語(yǔ)句: 1 SELECT T.*, LEVEL -----以下為更新內(nèi)容: 1、先查看總共有幾個(gè)等級(jí): 1 SELECT COUNT(LEVEL) 2 FROM EMP E 3 CONNECT BY PRIOR E.EMPNO = E.MGR 4 START WITH E.MGR IS NULL; 2、查看每個(gè)等級(jí)的人數(shù)。主要是通過(guò)LEVEL進(jìn)行GROUP BY 1 SELECT COUNT(LEVEL) 2 FROM EMP E 3 CONNECT BY PRIOR E.EMPNO = E.MGR 4 START WITH E.MGR IS NULL 5 GROUP BY LEVEL; 3、Oracle 10g提供了一個(gè)簡(jiǎn)單的connect_by_isleaf=1, 0 表示非葉子節(jié)點(diǎn) 1 SELECT LEVEL AS 等級(jí), CONNECT_BY_ISLEAF AS 是否是葉子節(jié)點(diǎn), E.* 2 FROM EMP E 3 CONNECT BY PRIOR E.EMPNO = E.MGR 4 START WITH E.MGR IS NULL 4、SYS_CONNECT_BY_PATH Oracle 9i提供了sys_connect_by_path(column,char),其中column 是字符型或能自動(dòng)轉(zhuǎn) 換成字符型的列名。它的主要目的就是將父節(jié)點(diǎn)到當(dāng)前節(jié)點(diǎn)的”path”按照指定的模式展現(xiàn)出現(xiàn)。這個(gè)函數(shù)只能使用在層次查詢中。 1 SELECT LEVEL AS 等級(jí), 2 CONNECT_BY_ISLEAF AS 是否是葉子節(jié)點(diǎn), 3 LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>') 4 FROM EMP E 5 CONNECT BY PRIOR E.EMPNO = E.MGR 6 START WITH E.MGR IS NULL; 5、修剪樹(shù)枝和節(jié)點(diǎn): 過(guò)濾掉編號(hào)是7566的數(shù)據(jù)(修剪節(jié)點(diǎn)),他指的是把這個(gè)節(jié)點(diǎn)給裁掉,但是并沒(méi)有破壞樹(shù)結(jié)構(gòu),它的子節(jié)點(diǎn)還是可以正常的顯示。 1 SELECT LEVEL AS 等級(jí), 2 CONNECT_BY_ISLEAF AS 是否是葉子節(jié)點(diǎn), 3 LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'), 4 E.* 5 FROM EMP E 6 WHERE e.empno != 7566 7 CONNECT BY PRIOR E.EMPNO = E.MGR 8 START WITH E.MGR IS NULL; 裁掉編號(hào)是7698的節(jié)點(diǎn)和它的子節(jié)點(diǎn): 1 SELECT LEVEL AS 等級(jí), 2 CONNECT_BY_ISLEAF AS 是否是葉子節(jié)點(diǎn), 3 LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'), 4 E.* 5 FROM EMP E 6 CONNECT BY PRIOR E.EMPNO = E.MGR 7 AND E.EMPNO != 7698 8 START WITH E.MGR IS NULL; 6、CONNECT_BY_ROOT的使用,oracle10g新增connect_by_root,用在列名之前表示此行的根節(jié)點(diǎn)的相同列名的值。 1 SELECT LEVEL AS 等級(jí), 2 CONNECT_BY_ISLEAF AS 是否是葉子節(jié)點(diǎn), 3 CONNECT_BY_ROOT ENAME, 4 LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'), 5 E.* 6 FROM EMP E 7 CONNECT BY PRIOR E.EMPNO = E.MGR 8 START WITH E.MGR IS NULL;
對(duì)于層次查詢?nèi)绻胦rder by排序,比如order by last_name則是先做完層次獲得level,然后按last_name 排序,這樣破壞了層次,比如特別關(guān)注某行的深度,按level 排序,也是會(huì)破壞層次的。在oracle10g中,增加了siblings 關(guān)鍵字的排序。 語(yǔ)法:order siblings by <expre> 它會(huì)保護(hù)層次,并且在每個(gè)等級(jí)中按expre排序。 1 SELECT LEVEL AS 等級(jí), 2 CONNECT_BY_ISLEAF AS 是否是葉子節(jié)點(diǎn), 3 LPAD(' ', LEVEL * 2 - 1) || SYS_CONNECT_BY_PATH(ENAME, '=>'), 4 E.* 5 FROM EMP E 6 CONNECT BY PRIOR E.EMPNO = E.MGR 7 START WITH E.MGR IS NULL 8 ORDER SIBLINGS BY E.ENAME; connect_by_iscycle(存在循環(huán),將返回1,否則返回0)The CONNECT_BY_ISCYCLE pseudocolumn returns 1 if the current row has a child which is also its ancestor. Otherwise it returns 0. I believe that we are who we choose to be. Nobody‘s going to come and save you, you‘ve got to save yourself. 我相信我們成為怎樣的人是我們自己的選擇。沒(méi)有人會(huì)來(lái)拯救你,你必須要自己拯救自己。
|
|