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

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

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

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數(shù)據(jù)加載中……

    SQL Server2005雜談(5):將聚合記錄集逆時針和順時針旋轉(zhuǎn)90度

    本文為原創(chuàng),如需轉(zhuǎn)載,請注明作者和出處,謝謝!

    上一篇:SQL Server2005雜談(4):在SQL Server2005中按列連接字符串的三種方法

        在輸出統(tǒng)計結(jié)果時可能需要將列變成行,而將聚合結(jié)果(如count、sum)作為記錄的第一行,先看如下的SQL語句:

    declare @t table(name varchar(20))
    insert @t
    select 'abc' union all
    select 'xxx' union all
    select 'xxx' union all
    select 'ttt'

    select * from @t

        在執(zhí)行上面的SQL語句后,會輸出如圖1所示的記錄集。

    圖1

        上圖顯示的是一個普通的記錄集,如果要統(tǒng)計name字段的每個值的重復數(shù),需要進行分組,如下面的SQL如示:

    select count(name) as c ,name  from @t group by name 


       
    執(zhí)行上面的SQL語句后的查詢結(jié)果如圖2所示。

    圖2

        如果我們有一個需求,需要如圖3所示的聚合結(jié)果。


    圖3

          從圖3可以看出,查詢結(jié)果正好是圖2的結(jié)果逆時針旋轉(zhuǎn)90度,也就是說,name列的值變成了列名,而c列的值變成了第一行的記錄。圖2所示的c和name字段消失了。

        當然,要達到這個結(jié)果并不困難,看如下的SQL語句:

    select (select count(name) from @t where name='abc'as abc, 
           (
    select count(name) from @t where name='ttt'as xxx,
           (
    select count(name) from @t where name='xxx'as ttt


        上 面的SQL語句會出輸出如圖3的查詢結(jié)果。但這里有個問題,上面的SQL語句是枚舉了name列所有可能的值,在本例中只有三個值 ('abc','ttt','xxx'),這非常好枚舉,但如果有很多值,SQL語句會變得非常長,非常不利于編寫。當然,可以通過編程的方式自動生成, 但最終結(jié)果仍然會生成很長的SQL語句。
       
    為了解決這個問題,在SQL Server2005中提供了一個pivot函數(shù),該函數(shù)可以很容易地輸出如圖3所示的記錄集,如下面的SQL語句所示:

    select * from @t pivot(count(name) for name in([abc] ,[ttt],[xxx]))


       
    在執(zhí)行上面的SQL語句同樣可以獲得圖3所示的查詢結(jié)果。實際上,pivot函數(shù)也起到了分組的作用。在使用pivot函數(shù)時應注意如下幾點:

    1. pivot函數(shù)需要指定聚合函數(shù),如count、sum等,for關(guān)鍵字和聚合函數(shù)都要使用需要聚合的字段名,在本例中是name。

    2. in關(guān)鍵字負責指定每組需要聚合的值,用[...]將這些值括起來。實際上,這些值也相當于我們第一種聚合方法中的where條件,例如,where name='abc'、where name='ttt',當然,這些值也是輸出記錄集的列名。

    3. 在最后要為pivot函數(shù)起一個別名。

        雖然當要聚合的值很多時(或不確定),也需要動態(tài)生成SQL語句,但使用pivot函數(shù)的SQL語句卻短很多。

        如 果我們還有一個需求,要將圖3的結(jié)果變成圖2的結(jié)果,也就是順時針旋轉(zhuǎn)90度,仍然以c和name作為字段名。也許方法很多,但SQL Server2005提供了一個unpivot函數(shù),該函數(shù)是pivot函數(shù)的逆過程。也就是將記錄集順時針旋轉(zhuǎn)90度,先看下面的SQL語句:
    declare @t table(name varchar(20))
    insert @t
    select 'abc' union all
    select 'xxx' union all
    select 'xxx' union all
    select 'ttt'
    ;
    with tt as(
    select * from @t pivot(count(name) for name in([abc] ,[ttt],[xxx])) p)
    select * from tt

        上面的SQL語句將輸出如圖3所示的結(jié)果。如果將最后一條SQL語句(select * from tt)換成如下的SQL語句,將輸出如圖2所示的結(jié)果。

    select * from tt  unpivot([c] for name in([abc] ,[xxx],[ttt])) p

        要注意的是,[c]中的c表示聚合結(jié)果列的字段名,name表示要聚合列的字段名,這兩個值可以是任意滿足字段名命名規(guī)則的字符串, [abc] ,[xxx],[ttt]分別是圖3所示的記錄集的字段名,這些值必須一致。執(zhí)行下面的SQL語句將獲得圖4的輸出結(jié)果。

    select * from tt  unpivot([統(tǒng)計值] for 統(tǒng)計名 in([abc] ,[xxx],[ttt])) p



    圖4




    Android開發(fā)完全講義(第2版)(本書版權(quán)已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2009-02-21 15:38 銀河使者 閱讀(1865) 評論(3)  編輯  收藏 所屬分類: SQL Serverdatabases 原創(chuàng)

    評論

    # re: SQL Server2005雜談(5):將聚合記錄集逆時針和順時針旋轉(zhuǎn)90度  回復  更多評論   

    用with處理似乎不大對,實際上的數(shù)據(jù)庫結(jié)構(gòu)不可能是只有一列

    比如:

    declare @t table(name varchar(20),test datetime)
    insert @t
    select 'abc','1970' union all
    select 'xxx','1971' union all
    select 'xxx','1972' union all
    select 'ttt','1973'
    select * from @t
    ;
    with tt as(
    select * from @t pivot(count(name) for name in([abc] ,[ttt],[xxx])) p)
    select * from tt

    返回結(jié)果是:

    1970-01-01 00:00:00.000 1 0 0
    1971-01-01 00:00:00.000 0 0 1
    1972-01-01 00:00:00.000 0 0 1
    1973-01-01 00:00:00.000 0 1 0

    顯然不是我們想要的結(jié)果呢,如果把datetime改成是ntext,那么

    根本都無法運行。

    或者我對with的操作不大理解,您可以按照我的補充內(nèi)容

    給出相應正確的with操作嗎?

    2009-11-21 11:43 | lvjin

    # re: SQL Server2005雜談(5):將聚合記錄集逆時針和順時針旋轉(zhuǎn)90度  回復  更多評論   

    這樣寫的話:

    SELECT *
    FROM
    (SELECT name
    FROM @t) AS SourceTable
    PIVOT
    (
    COUNT(name)
    FOR name IN ([abc] ,[ttt],[xxx])
    ) AS PivotTable;

    是可以得出正確結(jié)果:

    1 1 2
    2009-11-21 11:46 | lvjin

    # re: SQL Server2005雜談(5):將聚合記錄集逆時針和順時針旋轉(zhuǎn)90度  回復  更多評論   

    謝謝你的SQL雜談五篇文章,學習了
    2010-03-29 17:15 | y1sq1a
    主站蜘蛛池模板: 亚洲精品天堂在线观看| 免费无码专区毛片高潮喷水| 免费观看的毛片手机视频| 深夜久久AAAAA级毛片免费看| 亚洲国产日韩一区高清在线| 成年人免费观看视频网站| 99免费精品视频| 亚洲人成电影网站免费| 亚洲精品亚洲人成人网| 久久不见久久见中文字幕免费| 啊灬啊灬别停啊灬用力啊免费看| 成人黄网站片免费视频 | 亚洲午夜免费视频| 国产精品视_精品国产免费| 国产午夜无码精品免费看| 亚洲精品成人片在线播放 | 91视频免费网址| 久久亚洲中文字幕精品有坂深雪| 国产青草视频免费观看97| 无码国产精品一区二区免费vr | 亚洲va在线va天堂va不卡下载| 精品免费久久久久久成人影院| 亚欧免费一级毛片| 添bbb免费观看高清视频| 亚洲国产精品久久丫| 亚洲精品无码国产| 免费夜色污私人影院在线观看| 4虎1515hh永久免费| 三级黄色在线免费观看| 青青免费在线视频| 亚洲一线产品二线产品| 99久久亚洲精品无码毛片 | WWW亚洲色大成网络.COM| 亚洲欧洲校园自拍都市| 久久综合九九亚洲一区| 成年女人午夜毛片免费看| 99久久99热精品免费观看国产| 中文字幕视频免费在线观看| 国产亚洲福利一区二区免费看| 亚洲日本久久久午夜精品| 亚洲综合一区二区|