隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0

          導航

          <2008年9月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          公告

          關注我的新浪微博

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團隊

          隨筆分類(818)

          隨筆檔案(310)

          文章分類(1)

          文章檔案(8)

          相冊

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務

          代理網站

          關注的網站

          協議

          喜歡的Blog

          國內廣告平臺

          圖書出版

          在線培訓

          開發工具

          微博客戶端

          手機鈴聲

          操作系統

          • ReactOS
          • 一個與windowXP/2003兼容的操作系統

          數學

          文件格式

          源碼資源

          移動(Mobile)

          編程語言

          英語學習

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1972415
          • 排名 - 6

          最新評論

          閱讀排行榜

          評論排行榜

          妙用SQL Server聚合函數和子查詢迭代求和

          本文為原創,如需轉載,請注明作者和出處,謝謝!

          先看看下面的表和其中的數據:

          t_product


                      圖1

          該表有兩個字段:xhprice 其中xh是主索引字段,現在要得到如下的查詢結果:

              圖2

          從上面的查詢結果可以看出,totalprice字段值的規則是從第1條記錄到當前記錄的price之和。如第3條記錄的totalprice字段的值是10 + 25 + 36 = 71

          現在要通過t_product表中的數據生成圖2所示的查詢結果。可能會有很多讀者想到使用循環和游標,不過這種方式效率并不高,尤其在記錄非常多的情況。

          從圖2的查詢結果分析可知,這個結果仍然是求和的操作,只是并不是對所有的記錄求和,也不是分組求和,而是使用迭代的方式進行求和,求和的公式如下:

          當前記錄的totalprice = 當前記錄的price + 上一條記錄的totalprice

          上一條記錄的totalprice值也可看成是當前記錄以前所有記錄的price值之和。因此,可以對每一條記錄進行求和(使用sum函數),不過要求出當前記錄及以前的記錄的price之和,如下面的SQL語句:

          select a.xh, a.price,
          (
          select sum(price) from t_product b where b.xh <= a.xh) as totalprice 
          from t_product a

          從上面的SQL語句可以看出,使用了一個子查詢來求totalprice字段的值,基本原理就是根據當前記錄的xh值(a.xh)來計算從當前記錄往前所有記錄的price值之和,b.xh表示子查詢當前的xh值,在子查詢中,a.xh相當于常量。上面的SQL語句的查詢結果和圖2完全一樣。如果我們的需求是不包含當前記錄的price值,也就是說,計算totalprice字段的公式如下:

          當前記錄的totalprice = 上一條當前記錄的price + 上一條記錄的totalprice

          第一條記錄的totalprice值就是當前記錄的price值,查詢t_product表的結果如圖3所示。


          3

          要查詢出上述的記錄也很容易,只需要將<=改成<即可,SQL語句如下:


          select a.xh, a.price,
          (
          select sum(price) from t_product b where b.xh < a.xh) as totalprice 
          from t_product a

          但上面的SQL查詢出來的記錄的第一條的totalprice字段值為null,如圖4所示。


                圖4

          為了將這個null換成10,可以使用case語句,SQL語句如下:


          select xh, price, 
          (
          case  when totalprice is null then price else totalprice end ) as totalprice
          from
          (
          select a.xh, (select  sum(price) from t_product b where b.xh < a.xh)  as totalprice , a.price
          from t_product a)  x

          在上面的SQL語句共有三層select查詢,最里面一層如下:

          select  sum(price) from t_product b where b.xh < a.xh)

          中間一層的子查詢如下:

          select a.xh, (select  sum(price) from t_product b where b.xh < a.xh)  as totalprice , a.price
          from t_product a

          最外面一層當然就是整個select語句了。

          在執行上面的SQL后,將會得到和圖3一樣的查詢結果了。

          如果讀者不喜歡寫太長的SQL,可以將部分內容寫到函數里,代碼如下:

          create function mysum(@xh int@price intreturns int
          begin
            
          return (select 
                    (
          case when totalprice is null then @price  else totalprice endas totalprice 
                   
          from ( select  sum(price) as totalprice from t_product where xh < @xh) x)
          end

          可使用下面的SQL語句來使用這個函數:

          select xh, price, dbo.mysum(xh, price)  as totalprice
          from t_product

          在執行上面的SQL后,將得出如圖3所示的查詢結果。

          建立t_product表的SQL語句(SQL Server 2005)如下:

          SET ANSI_NULLS ON
          GO
          SET QUOTED_IDENTIFIER ON
          GO
          IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[t_product]'AND type in (N'U'))
          BEGIN
          CREATE TABLE [dbo].[t_product](
              
          [xh] [int] NOT NULL,
              
          [price] [int] NOT NULL,
           
          CONSTRAINT [PK_t_product] PRIMARY KEY CLUSTERED 
          (
              
          [xh] ASC
          )
          WITH (IGNORE_DUP_KEY = OFFON [PRIMARY]
          ON [PRIMARY]
          END





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

          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 2008-09-02 12:53 銀河使者 閱讀(2306) 評論(3)  編輯  收藏 所屬分類: SQL Serverdatabases 原創

          評論

          # re: 妙用SQL Server聚合函數和子查詢迭代求和  回復  更多評論   

          博主那名字總讓我會想起:李銀河
          2008-09-02 14:16 | 隔葉黃鶯

          # re: 妙用SQL Server聚合函數和子查詢迭代求和  回復  更多評論   

          李銀河,很耳熟,是誰?
          2008-09-02 14:39 | 銀河使者

          # re: 妙用SQL Server聚合函數和子查詢迭代求和  回復  更多評論   

          好,喜歡~贊一個
          2008-09-02 20:19 | 試客網
          主站蜘蛛池模板: 江都市| 信阳市| 通许县| 景泰县| 徐闻县| 扶绥县| 德昌县| 天台县| 博乐市| 阿尔山市| 榆林市| 阿巴嘎旗| 南雄市| 城固县| 连南| 信丰县| 霍山县| 剑阁县| 西林县| 云南省| 贡觉县| 当雄县| 铜梁县| 淮北市| 龙游县| 平谷区| 通海县| 方城县| 正镶白旗| 民勤县| 鸡西市| 宁陕县| 安远县| 合江县| 灯塔市| 浏阳市| 吴堡县| 河北省| 句容市| 鱼台县| 盐亭县|