<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 6  文章 - 129  trackbacks - 0
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(14)

    隨筆檔案(6)

    文章分類(467)

    文章檔案(423)

    相冊

    收藏夾(18)

    JAVA

    搜索

    •  

    積分與排名

    • 積分 - 825404
    • 排名 - 49

    最新評論

    閱讀排行榜

    評論排行榜

    原文:http://blog.csdn.net/bin_520_yan/article/details/5998349

    感覺這個CTE遞歸查詢蠻好用的,先舉個例子:

     

    1. use City;  
    2. go  
    3. create table Tree  
    4. (  
    5.   ID int identity(1,1) primary key not null,  
    6.   Name varchar(20) not null,  
    7.   Parent varchar(20) null  
    8. )  
    9. go  
    10. insert Tree values('大學',null)  
    11. insert Tree values('學院','大學')  
    12. insert Tree values('計算機學院','學院')  
    13. insert Tree values('網絡工程','計算機學院')  
    14. insert Tree values('信息管理','計算機學院')  
    15. insert Tree values('電信學院','學院')  
    16. insert Tree values('教務處','大學')  
    17. insert Tree values('材料科','教務處')  
    18. insert Tree values('招生辦','大學')  
    19. go  
    20. with CTE as  
    21. (  
    22. -->Begin 一個定位點成員  
    23.  select ID, Name,Parent,cast(Name as nvarchar(max)) as TE,0 as Levle from Tree where Parent is null  
    24. -->End   
    25. union all  
    26. -->Begin一個遞歸成員  
    27.  select Tree.ID, Tree.Name,Tree.Parent,cast(replicate(' ',len(CTE.TE))+'|_'+Tree.name as nvarchar(MAX)) as TE,Levle+1 as Levle  
    28.         from Tree inner join CTE  
    29.         on Tree.Parent=CTE.Name  
    30. -->End  
    31. )  
    32. select * from CTE order by ID  
    33. --1.將 CTE 表達式拆分為定位點成員和遞歸成員。  
    34. --2.運行定位點成員,創建第一個調用或基準結果集 (T0)。  
    35. --3.運行遞歸成員,將 Ti 作為輸入(這里只有一條記錄),將 Ti+1 作為輸出。  
    36. --4.重復步驟 3,直到返回空集。  
    37. --5.返回結果集。這是對 T0 到 Tn 執行 UNION ALL 的結果。  

     

    上面的SQL語句再次插入一條數據:

    insert Tree values('網絡1班','網絡工程')

         運行結果如下圖:

    圖1 運行結果

         注意點:貌似在遞歸成員處所選擇的字段都必須Tree表的數據,而不能是CTE結果集中的除了Tree中沒有而CTE中有的字段在這里才可以引用,比如字段TE。

        首先看下,遍歷的第1條記錄的SQL語句:

    1. select ID, Name,Parent,cast(Name as nvarchar(max)) as TE,0 as Levle from Tree where Parent is null  

     

       獲取的結果為:

       Name  Parent   TE    Levle

    -------------------------------------

         大學    NULL   大學     0

       遞歸第2次所獲取的結果集合的類SQL語句為:

    1. select Tree.ID, Tree.Name,Tree.Parent,cast(replicate(' ',len(CTE.TE))+'|_'+Tree.name as nvarchar(MAX)) as TE,Levle+1 as Levle  
    2. from Tree inner join  
    3.    (select ID, Name,Parent,cast(Name as nvarchar(max)) as TE,0 as Levle from Tree where Parent is null)  
    4. as CTE  
    5. on Tree.Parent=CTE.Name  

     

       上面的CTE子查詢的結果就是第一次遞歸查詢的結果集,上面SQL運行結果為:

       同樣的,將第二次遞歸查詢的上面三條記錄作為第三次查詢的‘定位成員’:

      【這里要注意,上面的三條記錄是從最后一條開始依次作為第三次遞歸的輸入的,即第一條是ID=9的記錄,接下來是7和2,關于第四次遞歸也類似】

       第三次遞歸類SQL語句

    1. select Tree.ID, Tree.Name,Tree.Parent,cast(replicate(' ',len(CTE.TE))+'|_'+Tree.name as nvarchar(MAX)) as TE,Levle+1 as Levle  
    2. from Tree inner join  
    3. (第二次遞歸查詢的SQL語句)as CTE  
    4. on Tree.Parent=CTE.Name  

     

       結果如下:

    其實每次遞歸的類SQL可為如下所示:

    1. select Tree.ID, Tree.Name,Tree.Parent,cast(replicate(' ',len(CTE.TE))+'|_'+Tree.name as nvarchar(MAX)) as TE,Levle+1 as Levle  
    2. from Tree inner join  
    3. (上次遞歸查詢的結果集,僅僅是上次那一次的,而不是以前的總和結果集)  
    4. as CTE  
    5. on Tree.Parent=CTE.Name  

     

     第四次遞歸一次類推,最后所查詢的結果為上面所有遞歸的union。

     續:在上面的SQ語句查詢結果中,ID為10的記錄應該要放在ID為4的后面。

     往數據表中再次添加兩條記錄:

    insert Tree values('計科','計算機學院')
    insert Tree values('我','網絡1班') 

    再次修改上面的SQL語句:

    1. with CTE as    
    2. (     
    3. -->Begin 一個定位點成員     
    4.  select ID, Name,Parent,cast(Name as nvarchar(max)) as TE,  
    5.         ROW_NUMBER()over(order by getdate()) as OrderID  
    6.         --最關鍵是上面這個字段,要獲取排序字段,按字符串來排序。  
    7.         --其中窗口函數必須要使用order by,但是不能用整型,那就用時間吧  
    8.         from Tree where Parent is null    
    9. -->End      
    10. union all     
    11. -->Begin一個遞歸成員     
    12.  select Tree.ID, Tree.Name,Tree.Parent,cast(replicate(' ',len(CTE.TE))+'|_'+Tree.name as nvarchar(MAX)) as TE,  
    13.         CTE.OrderID*100+ROW_NUMBER()over(Order by GETDATE()) as OrderID  
    14.         from Tree inner join CTE     
    15.         on Tree.Parent=CTE.Name     
    16. -->End     
    17. )     
    18. select * from CTE  
    19. order by LTRIM(OrderID)--最后將這個整型數據轉換為字符串型的進行排序  
    20.   
    21. --有時候整型可以比大小,字符串也可以,字符串比的大小是一位一位進行字符比較的  
    22. --整型+字符串==整型,只有字符串+字符串==兩個字符串的并和  
    23. --遞歸查詢中:第二條記錄可以引用第一條記錄的值  
    24. --動態加載記錄時,同一個等級的記錄識別符:RowNumber()over(order by getdate())  
    25. --延伸:可以動態獲取某個部門下的所以子部門。也可以獲取該部門上級的所以部門  
    26.   
    27. --總結:首先要拼湊出一個整型數據,然后轉換為字符串,最后是進行字符串的order,而不是整型數據的order,  

     

    最后的結果為:

    圖2 運行結果

    這樣,無論用戶插入多少條記錄都可以進行按部門,按規律進行查詢。



    posted on 2014-07-17 14:46 Ke 閱讀(743) 評論(0)  編輯  收藏 所屬分類: sql server
    主站蜘蛛池模板: 国产精品亚洲а∨天堂2021| 久99久无码精品视频免费播放| 免费99热在线观看| 怡红院免费的全部视频| 亚洲人成网男女大片在线播放| 小小影视日本动漫观看免费| GOGOGO免费观看国语| 亚洲国产超清无码专区| gogo全球高清大胆亚洲| 精品免费久久久久久久| 九九久久精品国产免费看小说| 亚洲精品无码久久毛片波多野吉衣| 国产免费人视频在线观看免费| 伊人久久免费视频| 日韩精品亚洲专区在线影视| 蜜芽亚洲av无码精品色午夜| 亚洲成人一区二区| 免费观看AV片在线播放| 精品国产呦系列在线观看免费| 亚洲国产成a人v在线观看| 亚洲日韩欧洲无码av夜夜摸| 日韩一级视频免费观看| 中文字幕免费观看| 国产一级高青免费| 污污免费在线观看| 亚洲熟妇AV一区二区三区浪潮| 婷婷亚洲久悠悠色悠在线播放| 亚洲国产免费综合| 午夜视频免费成人| 波多野结衣免费在线| a毛片在线免费观看| 免费人成大片在线观看播放| 国产成人亚洲综合一区| 亚洲精品mv在线观看| 国产亚洲综合久久系列| 亚洲精品无码永久在线观看| 女人张腿给男人桶视频免费版| 啦啦啦完整版免费视频在线观看| 两个人的视频www免费| 一区二区三区免费在线视频| 亚洲av最新在线观看网址|