這幾個關(guān)鍵是查詢遞歸數(shù)據(jù)的,形成一個樹狀結(jié)構(gòu)。目前只有oracle支持,其他數(shù)據(jù)都要結(jié)合存儲過程實現(xiàn)
語法: select * from some_table [where 條件1] connect by [條件2] start with [條件3];
其中 connect by 與 start with 語句擺放的先后順序不影響查詢的結(jié)果,[where 條件1]可以不需要。 [where 條件1]、[條件2]、[條件3]各自作用的范圍都不相同:
[where 條件1]是在根據(jù)“connect by [條件2] start with [條件3]”選擇出來的記錄中進行過濾,是針對單條記錄的過濾, 不會考慮樹的結(jié)構(gòu);
[條件2]指定構(gòu)造樹的條件,以及對樹分支的過濾條件,在這里執(zhí)行的過濾會把符合條件的記錄及其下的所有子節(jié)點都過濾掉;
[條件3]限定作為搜索起始點的條件,如果是自上而下的搜索則是限定作為根節(jié)點的條件,如果是自下而上的搜索則是限定作為葉子節(jié)點的條件;
看下面的例子 此例以oracle中scott模式下的emp表為例。此表中empno為員工號,mgr為此員工的主管對應(yīng)的員工號;考慮員工下轄若干員工,下轄的員工又有下轄的員工,正好形成一個樹狀結(jié)構(gòu) 以SCOTT為例 select * from scott.emp start with ename='SCOTT' CONNECT BY prior empno=mgr; 找員工姓名為SCOTT,且前一條記錄的員工號是及其直接下轄或者間接下轄的所有員工
對prior的說明: prior存在于[條件2]中,可以不要,不要的時候只能查找到符合“start with [條件3]”的記錄,不會在尋找這些記錄的子節(jié)點。要的時候有兩種寫法:connect by prior empno=mgr 或 connect by empno=prior mgr,前一種寫法表示采用自上而下的搜索方式(先找父節(jié)點然后找子節(jié)點),后一種寫法表示采用自下而上的搜索方式(先找葉子節(jié)點然后找父節(jié)點)。北大青鳥合肥圣大中心的畢業(yè)項目關(guān)于權(quán)限的也有類似的使用場景。
[執(zhí)行原理] 遍歷表中的每條記錄,對比是否滿足start with后的條件,如果不滿足則繼續(xù)下一條, 如果滿足則以該記錄為根節(jié)點,然后遞歸尋找該節(jié)點下的子節(jié)點, 查找條件是connect by后面指定的條件,比如上面的例子,是當(dāng)前記錄的empno等于其子節(jié)點的mgr,如此循環(huán)直到遍歷完整個表的所有記錄 如果數(shù)據(jù)有問題,出現(xiàn)循環(huán),即a是b的經(jīng)理,b是c的經(jīng)理,c又是a的經(jīng)理,查詢會出現(xiàn)ORA-01436: 用戶數(shù)據(jù)中的 CONNECT BY 循環(huán) 的錯誤,可在connect by后面添加nocycle 解決這個問題。
結(jié)合 sys_connect_by_path 函數(shù),可以做出更好的效果,參考這個sql語句
select empno,ename,sys_connect_by_path(ename,'/') from scott.emp start with ename='SCOTT' CONNECT BY prior empno=mgr;