原文 BlueShop

遞迴 CTE 結構至少必須包含一個錨點成員與一個遞迴成員。下列虛擬程式碼顯示含有單一錨點成員與單一遞迴成員的簡單遞迴 CTE 所具備的元件。

   1: WITH cte_name ( column_name [,...n] )
   2: AS
   3: (
   4: CTE_query_definition –- Anchor member is defined.
   5: UNION ALL
   6: CTE_query_definition –- Recursive member is defined referencing cte_name.
   7: )
   8: -- Statement using the CTE
   9: SELECT *
  10: FROM cte_name


遞迴執行的語意如下:
將 CTE 運算式分割為錨點成員與遞迴成員。
執行錨點成員以建立第一個引動過程或基底結果集 (T0)。
執行遞迴成員,以 Ti 做為輸入,而以 Ti+1 做為輸出。
重複步驟 3,直到傳回空的結果集為止。
傳回結果集。這是 T0 至 Tn 的 UNION ALL。

版上範例 :

   1: with directsales(up_dno,dno,lvl)
   2: as(
   3: --Anchor查詢
   4: select up_dno,dno,1 as lvl
   5: from dbo_dsales where dno='A'
   6: union all
   7: --Recursive查詢
   8: select a.up_dno,a.dno,lvl+1
   9: from dbo_dsales a,directsales b
  10: where a.up_dno=b.dno
  11: )
  12: --執行CTE查詢
  13: select up_dno as 上線直銷商,dno as 直銷商,lvl as 階層
  14: from directsales

所以錨點成員是
select up_dno,dno,1 as lvl from dbo_dsales where dno='A'
也就是 
   up_dno,dno,lvl
    null A  1
那遞迴成員是
select a.up_dno,a.dno,lvl+1 from dbo_dsales a,directsales b where a.up_dno=b.dno
也就是
在第一次跑時,b.dno = A
得到
   up_dno,dno,lvl
    A   B  2
    A   C  2
在第二次跑時,b.dno = B,C
得到
   up_dno,dno,lvl
    B   D  3
    B   E  3
    C   F  3
    C   G  3
    C   H  3
在第三次跑時,b.dno = D,E,F,G,H
得到
   up_dno,dno,lvl
    D   I  4
    D   J  4
    F   K  4
    G   L  4
在第四次跑時,b.dno = I,J,K,L
得到
   up_dno,dno,lvl
    J   M  5
    L   N  5
在第五次跑時,b.dno = M,N
得到 無符合資料(傳回空的結果集)
所以遞迴停止
所以最後得到結果為
   up_dno,dno,lvl
    null  A  1
    A   B  2
    A   C  2
    B   D  3
    B   E  3
    C   F  3
    C   G  3
    C   H  3
    D   I  4
    D   J  4
    F   K  4
    G   L  4
    J   M  5
    L   N  5


個人實作:

資料庫結構大概是:

sys_dep_id(部門ID) sys_dep_up(上層部門ID)
201 101
301 201
302 201
401 301
402 301
403 301
501 401
   1: with myview (sys_dep_up,sys_dep_id ) as
   2: (select sys_dep_up,sys_dep_id
   3: from dbo.sys_dep where sys_dep_up = 301
   4: union all
   5: select a.sys_dep_up,a.sys_dep_id
   6: from dbo.sys_dep a,myview b
   7: where a.sys_dep_up=b.sys_dep_id)
   8:  
   9: select sys_dep_id as alldepid
  10: from myview

結果為: 401,402,403,501

arrow
arrow

    jason0324 發表在 痞客邦 留言(0) 人氣()