妙用SQL Server聚合函数和子查询迭代求和

来源:互联网 发布:数据挖掘的算法有哪些 编辑:程序博客网 时间:2024/04/29 02:21

先看看下面的表和其中的数据:

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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 高中生晚上偷家里电脑上网怎么办 住高层睡不好觉怎么办 水瓶座如果恨我们了该怎么办 不锈钢保温瓶不保温了怎么办 壁纸颜色选深了怎么办 客厅壁纸太暗了怎么办 别人说你衣服丑怎么办 高楼热水器风大熄火怎么办 1楼独立下水2楼怎么办 宜家家具不会装怎么办 服务行业遇到低素质客户怎么办 服务类没有进项票怎么办 教师对学生缺乏耐心怎么办 买了竹料烂尾楼怎么办 刚毕业想换工作怎么办 客厅灯变不了光怎么办 塑料镀铝浸底漆咬底怎么办 标志408钥匙掉了怎么办 房本测绘页丢了怎么办 房本测绘页信息有误怎么办 税务登记证办完没有年检怎么办 建筑施工升降机司机证怎么办 北京建筑施工证怎么办呢 模拟城市5水抽干了怎么办 ip地址错误网络无法接通怎么办 rhino模型太大打开半天怎么办 日本新干线车票丢了怎么办 房间太干燥怎么办又热 薄荷叶子全干了怎么办 水培栀子花叶子蔫了怎么办 薄荷叶叶边干了怎么办 碗莲叶子发黑腐烂怎么办 龟背叶叶子蔫了怎么办 夏天龟背竹蔫了怎么办 春羽叶子长黄斑怎么办 百合竹叶子发黄掉落怎么办 凤尾蕨叶子蔫了怎么办 绿地珊瑚蕨干了怎么办 翠云草叶子蔫了怎么办 珊瑚蕨叶子烂了怎么办 黑骨茶叶子黑斑怎么办