SQL 数据聚合

连续聚合

下面的例子将使用一个EmpOrdersr汇总表,每位雇员在每个月占一行,包含该雇员在一个月内处理过的订单数量,运行下代码创建数据:

复制代码
CREATE TABLE EmpOrders
    (
      empid INT NOT NULL ,
      ordmonth DATE NOT NULL ,--只取到月份2015-07-07
      qty INT NOT NULL ,
      PRIMARY KEY ( empid, ordmonth )
    )
go 
INSERT  INTO EmpOrders
        ( empid ,
          ordmonth ,
          qty 
        )
        SELECT  o.empid ,
                DATEADD(MONTH, DATEDIFF(MONTH, 0, o.orderdate), 0) AS ordmonth ,
                SUM(qty) AS qty
        FROM    Sales.Orders AS o
                JOIN Sales.OrderDetails AS od ON o.orderid = od.orderid
        GROUP BY empid ,
                DATEADD(MONTH, DATEDIFF(MONTH, 0, o.orderdate), 0)
复制代码

查询:

SELECT  empid ,
        ordmonth ,
        qty
FROM    EmpOrders
ORDER BY empid ,
        ordmonth

将输出以下内容

接下来讲讲各类聚合……

1.累积聚合

 为每个雇员和每个月,返回从其开始有订单操作以来到该月份处理过的订单总量和每月的平均量,结果如下,怎么做?

复制代码
SELECT  o1.empid ,
        o1.ordmonth ,
        o1.qty AS qtythismonth ,
        SUM(o2.qty) AS totalqty ,
        CAST(AVG(1. * o2.qty) AS NUMERIC(12, 2)) AS avgqty
FROM    EmpOrders AS o1
        JOIN EmpOrders AS o2 ON o2.empid = o1.empid
                                AND o2.ordmonth <= o1.ordmonth
GROUP BY o1.empid ,
        o1.ordmonth ,
        o1.qty
ORDER BY o1.empid ,
        o1.ordmonth
复制代码

 

若想得到雇员达到累积总量<1000之前的每月聚合值,怎么做?

 

复制代码
SELECT  o1.empid ,
        o1.ordmonth ,
        o1.qty AS qtythismonth ,
        SUM(o2.qty) AS totalqty ,
        CAST(AVG(1. * o2.qty) AS NUMERIC(12, 2)) AS avgqty
FROM    EmpOrders AS o1
        JOIN EmpOrders AS o2 ON o2.empid = o1.empid
                                AND o2.ordmonth <= o1.ordmonth
GROUP BY o1.empid ,
        o1.ordmonth ,
        o1.qty
        HAVING SUM(o2.qty)<1000
ORDER BY o1.empid ,
        o1.ordmonth
复制代码

 对总量做一次HAVING过滤 HAVING SUM(o2.qty)<1000,而不是用WHERE,因为过滤是的聚合,而不是属性。  

 

2.滑动聚合

 滑动聚合是对序列内的一个滑动窗口进行的聚合计算,而不是从序列的开始计算到当前位置。

 求雇员最近三个月(包括本月)的平均订单量(移动平均数),得到以下结果:

复制代码
SELECT  o1.empid ,
        o1.ordmonth ,
        o1.qty AS qtythismonth ,
        SUM(o2.qty) AS totalqty ,
        CAST(AVG(1. * o2.qty) AS NUMERIC(12, 2)) AS avgqty
FROM    EmpOrders AS o1
        JOIN EmpOrders AS o2 ON o2.empid = o1.empid
                                AND (o2.ordmonth <= o1.ordmonth AND o2.ordmonth > DATEADD(MONTH,-3,o1.ordmonth))
GROUP BY o1.empid ,
        o1.ordmonth ,
        o1.qty
ORDER BY o1.empid ,
        o1.ordmonth
复制代码

这里使用的是o2.ordmonth> 3个月之前的月份 and o2.ordmonth<=o1.当前月份

 

3.年初至今

聚合按年单位算,如求每个雇员每年内的每个月份的聚合,该怎样写?结果如下:

复制代码
SELECT  o1.empid ,
       CONVERT( VARCHAR(7),o1.ordmonth ,121) AS  ordmonth,
        o1.qty AS qtythismonth ,
        SUM(o2.qty) AS totalqty ,
        CAST(AVG(1. * o2.qty) AS NUMERIC(12, 2)) AS avgqty
FROM    EmpOrders AS o1
        JOIN EmpOrders AS o2 ON o2.empid = o1.empid
                                AND ( o2.ordmonth <= o1.ordmonth
                                      AND o2.ordmonth >= CAST(CAST(YEAR(o1.ordmonth) AS CHAR(4))
                                      + '0101' AS DATETIME)
                                    )
GROUP BY o1.empid ,
        o1.ordmonth ,
        o1.qty
ORDER BY o1.empid ,
        o1.ordmonth
复制代码

 

所有聚合函数都会忽略NULL值,只有一个例外:Count(*)

聚合中常见的函数为分组函数GROUP BY ,要注意的是 GROUP BY 原则 select后面所有列中 没有使用聚合函数的列必须出现在GROUP BY 后面


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值