Oracle遞迴函式

來源:互聯網
上載者:User

Oracle遞迴函式

Oracle start with connect by 用法

oracle中 connect by prior 遞迴演算法
 
Oracle中start with...connect by prior子句用法 connect by 是結構化查詢中用到的,其基本文法是:
 select ... from tablename start with 條件1
 connect by 條件2
 where 條件3;
 例:
 select * from table
 start with org_id = 'HBHqfWGWPy'
 connect by prior org_id = parent_id;
 
    簡單說來是將一個樹狀結構儲存在一張表裡,比如一個表中存在兩個欄位:
 org_id,parent_id那麼通過表示每一條記錄的parent是誰,就可以形成一個樹狀結構。
      用上述文法的查詢可以取得這棵樹的所有記錄。
      其中:
      條件1 是根結點的限定語句,當然可以放寬限定條件,以取得多個根結點,實際就是多棵樹。
      條件2 是串連條件,其中用PRIOR表示上一條記錄,比如 CONNECT BY PRIOR org_id = parent_id就是說上一條記錄的org_id 是本條記錄的parent_id,即本記錄的父親是上一條記錄。
      條件3 是過濾條件,用於對返回的所有記錄進行過濾。
 
    簡單介紹如下:
      早掃描樹結構表時,需要依此訪問樹結構的每個節點,一個節點只能訪問一次,其訪問的步驟如下:
      第一步:從根節點開始;
      第二步:訪問該節點;
      第三步:判斷該節點有無未被訪問的子節點,若有,則轉向它最左側的未被訪問的子節,並執行第二步,否則執行第四步;
      第四步:若該節點為根節點,則訪問完畢,否則執行第五步;
      第五步:返回到該節點的父節點,並執行第三步驟。
 
    總之:掃描整個樹結構的過程也即是中序遍曆樹的過程。

在CentOS 6.4下安裝Oracle 11gR2(x64)

Oracle 11gR2 在VMWare虛擬機器中安裝步驟

Debian 下 安裝 Oracle 11g XE R2

Oracle 遞迴查詢
 
    1. 樹結構的描述
 樹結構的資料存放在表中,資料之間的層次關係即父子關係,通過表中的列與列間的關係來描述,如EMP表中的EMPNO和MGR。EMPNO表示該僱員的編號,MGR表示領導該僱員的人的編號,即子節點的MGR值等於父節點的EMPNO值。在表的每一行中都有一個表示父節點的MGR(除根節點外),通過每個節點的父節點,就可以確定整個樹結構。
 在SELECT命令中使用CONNECT BY 和藹START WITH 子句可以查詢表中的樹型結構關係。其命令格式如下:
 SELECT 。。。
 CONNECT BY {PRIOR 列名1=列名2|列名1=PRIOR 裂名2}
 [START WITH];
 其中:CONNECT BY子句說明每行資料將是按層次順序檢索,並規定將表中的資料連入樹型結構的關係中。PRIORY運算子必須放置在串連關係的兩列中某一個的前面。對於節點間的父子關係,PRIOR運算子在一側表示父節點,在另一側表示子節點,從而確定尋找樹結構是的順序是自頂向下還是自底向上。在串連關係中,除了可以使用列名外,還允許使用列運算式。START WITH 子句為可選項,用來標識哪個節點作為尋找樹型結構的根節點。若該子句被省略,則表示所有滿足查詢條件的行作為根節點。
 START WITH: 不但可以指定一個根節點,還可以指定多個根節點。
 2. 關於PRIOR
 運算子PRIOR被放置於等號前後的位置,決定著查詢時的檢索順序。
 PRIOR被置於CONNECT BY子句中等號的前面時,則強制從根節點到分葉節點的順序檢索,即由父節點向子節點方向通過樹結構,我們稱之為自頂向下的方式。如:
 CONNECT BY PRIOR EMPNO=MGR
 PIROR運算子被置於CONNECT BY 子句中等號的後面時,則強制從分葉節點到根節點的順序檢索,即由子節點向父節點方向通過樹結構,我們稱之為自底向上的方式。例如:
 CONNECT BY EMPNO=PRIOR MGR
 在這種方式中也應指定一個開始的節點。
 3. 定義尋找起始節點
      在自頂向下查詢樹結構時,不但可以從根節點開始,還可以定義任何節點為起始節點,以此開始向下尋找。這樣尋找的結果就是以該節點為開始的結構樹的一枝。
 4.使用LEVEL
 在具有樹結構的表中,每一行資料都是樹結構中的一個節點,由於節點所處的層次位置不同,所以每行記錄都可以有一個層號。層號根據節點與根節點的距離確定。不論從哪個節點開始,該起始根節點的層號始終為1,根節點的子節點為2, 依此類推。
 5.節點和分支的裁剪
 在對樹結構進行查詢時,可以去掉表中的某些行,也可以剪掉樹中的一個分支,使用WHERE子句來限定樹型結構中的單個節點,以去掉樹中的單個節點,但它卻不影響其後代節點(自頂向下檢索時)或前輩節點(自底向頂檢索時)。
 6.排序顯示
 象在其它查詢中一樣,在樹結構查詢中也可以使用ORDER BY 子句,改變查詢結果的顯示順序,而不必按照遍曆樹結構的順序
 

----------------------------------------------------------------------------------------------------------
 
oracle 提供了start with connect by 文法結構可以實現遞迴查詢。
 
1. 一個簡單舉例:
 SQL> select *  from test;
 
BILL_MONTH          DAY_NUMBER MSISDN
 -------------------- ---------- --------------------
 200803                        1 13800
 200803                        3 13800
 200803                        2 13800
 200803                        2 13801
 200803                        4 13804
 200803                        5 13804
 200803                        7 13804
 200803                        8 13804
 200803                        6 13802
 200803                        6 13801
 200803                        7 13801
 200803                        8 13801
 
12 rows selected
 
SQL>
 SQL> select * from test
 2      start with day_number=1
 3      connect by  prior day_number=day_number-1 and prior msisdn= msisdn
 4      ;
 
BILL_MONTH          DAY_NUMBER MSISDN
 -------------------- ---------- --------------------
 200803                        1 13800
 200803                        2 13800
 200803                        3 13800
 
SQL>
 

上面的語句尋找出了從1開始,並且day_number 逐漸+1 遞增的,並且 msisdn 相同的哪些個資料.
 

2. start with  connect by 文法結構
 如上面說看到的 例子, 其文法結構為  start with condition  connect by  condition (含 prior 關鍵字)
 start with conditon 給出的seed 資料的範圍, connect by  後面給出了遞迴查詢的條件,prior 關鍵字表示父資料,prior 條件表示子資料需要滿足父資料的什麼條件。
 
在下面的這個start with connect by 結構中,就表示 尋找出了從1開始,並且day_number 逐漸+1 遞增的,並且 msisdn 相同的那些個資料.
 
start with day_number=1
 connect by  prior day_number=day_number-1 and prior msisdn= msisdn
 
3.  執行計畫
 對於這個特殊的文法結構,我們來看看它的執行計畫。
 通過下面的執行計畫,我們可以看出,對於簡單的訪問一個對象的遞迴查詢,實際上oracle 要三次訪問要查詢的對象。因此,這一個告訴我們,在使用遞迴查詢時,一定要謹慎,因為即使原表資料不多,但是三倍的訪問喜愛來,代價也會很大。
 
SQL> explain plan for
 2
 2  select * from  test
 3    --where  bill_month='200803'
 4    start with day_number=1
 5    connect by  prior day_number=day_number-1 and prior msisdn= msisdn
 6  ;
 
Explained
 
SQL> select *  from  table( dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
 --------------------------------------------------------------------------------
 -------------------------------------------------------------------------
 | Id  | Operation                |  Name      | Rows  | Bytes | Cost  |
 -------------------------------------------------------------------------
 |  0 | SELECT STATEMENT          |            |      |      |      |
 |*  1 |  CONNECT BY WITH FILTERING|            |      |      |      |
 |*  2 |  FILTER                  |            |      |      |      |
 |  3 |    TABLE ACCESS FULL      | TEST        |      |      |      |
 |  4 |  NESTED LOOPS            |            |      |      |      |
 |  5 |    BUFFER SORT            |            |      |      |      |
 |  6 |    CONNECT BY PUMP      |            |      |      |      |
 |*  7 |    TABLE ACCESS FULL      | TEST        |      |      |      |
 |  8 |  TABLE ACCESS FULL      | TEST        |      |      |      |
 -------------------------------------------------------------------------
 Predicate Information (identified by operation id):
 ---------------------------------------------------
 1 - filter("TEST"."DAY_NUMBER"=1)
 2 - filter("TEST"."DAY_NUMBER"=1)
 
PLAN_TABLE_OUTPUT
 --------------------------------------------------------------------------------
 7 - filter("TEST"."MSISDN"=NULL AND "TEST"."DAY_NUMBER"-1=NULL)
 Note: rule based optimization
 
23 rows selected
 
SQL>
 

另外,發現了在含有其他條件的遞迴中,是先處理所有的遞迴查詢,最後才用加入的條件過濾.
 請看下面的例子。
 和上面的執行計畫對比下我們可以知道,加入條件  where  bill_month='200803' 後,實際上卻是在遞迴完成後,最後才執行的    1 - filter("TEST"."BILL_MONTH"='200803') 。
 
所以,為了確保語句的效能,不要直接加入條件在start with connect by 結構中,而是要想辦法將原表的資料控制住。這個可以採用子查詢的辦法,或者使用暫存資料表等(最好採用暫存資料表,將資料量從本源上控制住;因為從子查詢的執行計畫我們可以看到,它每次也都是訪問全表,再用條件過濾,要重複三次,不是一次過濾就夠了).

更多詳情見請繼續閱讀下一頁的精彩內容:

  • 1
  • 2
  • 下一頁

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.