<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
    主站蜘蛛池模板: 波多野结衣免费在线观看| 国产大片免费天天看| 中文字幕乱码亚洲无线三区| 亚洲视频手机在线| 亚洲尹人九九大色香蕉网站| 亚洲综合无码一区二区| 亚洲白色白色永久观看| 亚洲一区二区三区精品视频| 亚洲a视频在线观看| 亚洲综合一区国产精品| 亚洲av无码成人精品区一本二本 | 日韩精品成人亚洲专区| 成人亚洲网站www在线观看| 国产伦精品一区二区三区免费迷 | 青青在线久青草免费观看| 黄页免费的网站勿入免费直接进入| 7723日本高清完整版免费| 国产精品成人免费一区二区 | 永久在线观看www免费视频| 亚洲一级毛片免费在线观看| 美女网站免费福利视频| 日本免费中文字幕在线看| 亚洲А∨精品天堂在线| 国产亚洲精AA在线观看SEE| 亚洲精品福利网站| 99久久国产亚洲综合精品| 美女视频黄a视频全免费网站色| 国产精品永久免费| 99爱在线观看免费完整版| 两个人的视频高清在线观看免费| 国产成人免费a在线视频色戒| 亚洲一区二区三区在线播放| 亚洲精品又粗又大又爽A片| 日韩高清在线高清免费| 美女被免费网站在线视频免费 | 久久久久亚洲精品日久生情| 免费一级黄色毛片| 国产午夜影视大全免费观看| 午夜一区二区免费视频| 一二三四在线播放免费观看中文版视频 | 亚洲熟妇AV乱码在线观看|