11GR2遞迴With子查詢

壹頁書發表於2015-12-28
11GR2增加了遞迴With子查詢
詳見 劍破冰山 429頁

樹形遍歷有了新方法.

原來使用sys_connect_by_path函式
  1. select  
  2.     employee_id,  
  3.     first_name,  
  4.     manager_id,  
  5.     level,  
  6.     sys_connect_by_path(employee_id,'\'as path,  
  7.     connect_by_root(first_name) as top_manager  
  8. from employees  
  9. start with manager_id is null   
  10. connect by prior employee_id=manager_id; 

遞迴With新寫法.
由兩個SQL union all而成.
上面的SQL是起始的條件.
下面的SQL是遞迴的條件.
  1. with t(employee_id,first_name,manager_id,the_level,path,top_manager) as   
  2. (  
  3.     select   
  4.         employee_id,  
  5.         first_name,  
  6.         manager_id,  
  7.         1 as the_level,  
  8.         '\'||employee_id as path,  
  9.         first_name as top_manager  
  10.     from employees   
  11.     where manager_id is null  
  12.     union all  
  13.     select   
  14.         e.employee_id,  
  15.         e.first_name,  
  16.         e.manager_id,  
  17.         1+t.the_level as the_level,  
  18.         t.path||'\'||e.employee_id as path,  
  19.         t.top_manager  
  20.     from t,employees e  
  21.     where t.employee_id=e.manager_id  
  22. )  
  23. select * from t;  

搜尋子句
SEARCH
①   { DEPTH FIRST BY c_alias [, c_alias]...
        [ ASC | DESC ]
        [ NULLS FIRST | NULLS LAST ]
②   | BREADTH FIRST BY c_alias [, c_alias]...
        [ ASC | DESC ]
        [ NULLS FIRST | NULLS LAST ]
     }
③    SET ordering_column

注:
①DEPTH FIRST表示按深度優先的順序來輸出。BY後面的列名及其升降序、空值放置順序指明瞭在深度優先的前提下,同一層次的資料的排序情況。
    這和原來CONNECT BY查詢中的ORDER SIBLING BY子句是一樣的。
②BREADTH FIRST表示按廣度優先的順序來輸出。BY後面的列名及其升降序、空值放置順序指明瞭在廣度優先的前提下,同一層次的資料的排序情況。
③列名ordering_column用於存放排序後的序號,是一個從1開始的連續正整數。後續的查詢中可以利用這個列得知某行資料在整個結果集中的位置。

sys_connect_by_path結果:


深度優先遍歷
  1. with t(employee_id,first_name,manager_id,the_level,path,top_manager) as   
  2. (  
  3.     select   
  4.         employee_id,  
  5.         first_name,  
  6.         manager_id,  
  7.         1 as the_level,  
  8.         '\'||employee_id as path,  
  9.         first_name as top_manager  
  10.     from employees   
  11.     where manager_id is null  
  12.     union all  
  13.     select   
  14.         e.employee_id,  
  15.         e.first_name,  
  16.         e.manager_id,  
  17.         1+t.the_level as the_level,  
  18.         t.path||'\'||e.employee_id as path,  
  19.         t.top_manager  
  20.     from t,employees e  
  21.     where t.employee_id=e.manager_id  
  22. )  
  23. search depth first by manager_id set seq  
  24. select * from t;  


廣度優先遍歷
  1. with t(employee_id,first_name,manager_id,the_level,path,top_manager) as   
  2. (  
  3.     select   
  4.         employee_id,  
  5.         first_name,  
  6.         manager_id,  
  7.         1 as the_level,  
  8.         '\'||employee_id as path,  
  9.         first_name as top_manager  
  10.     from employees   
  11.     where manager_id is null  
  12.     union all  
  13.     select   
  14.         e.employee_id,  
  15.         e.first_name,  
  16.         e.manager_id,  
  17.         1+t.the_level as the_level,  
  18.         t.path||'\'||e.employee_id as path,  
  19.         t.top_manager  
  20.     from t,employees e  
  21.     where t.employee_id=e.manager_id  
  22. )  
  23. search BREADTH first by manager_id set seq  
  24. select * from t;  


參考:
http://www.oracle.com/technetwork/cn/articles/hartley-recursive-086819-zhs.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1965778/,如需轉載,請註明出處,否則將追究法律責任。

相關文章