计算多个日期的运行总计

时间:2016-11-11 15:17:08

标签: sql sql-server tsql sql-server-2012 window-functions

请参阅问题的底部以获取测试数据..

我有以下数据..

salesorder  datee
1          2016-11-10
1          2016-11-10
2          2016-11-09
2          2016-11-09

现在我想显示我的数据,如下所示

datee       Summ
2016-11-09  4
2016-11-10  6

所以我使用了以下查询,它给出了确切的结果

select distinct 
datee,
sum(salesorder) over (order by datee)
from
#test

但上面查询的问题是,它使用Range选项并使用磁盘假脱机(如果工作表有记录,那么它是基于磁盘的假脱机),而不是在内存假脱机中。你可以使用下面验证相同

set statistics io on
select distinct 
datee,
sum(salesorder) over (order by datee)
from
#test
  

表'工作台'。扫描计数3,逻辑读取21,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。   表'#test _______________________________________________________________________________________________________________ 00000001A8B8'。扫描计数1,逻辑读取1,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。

获取InMemory假脱机的一种方法是使用Rows选项,如下所示

select 
datee,
sum(salesorder) over ( order by datee rows between  unbounded preceding and  current row )
from
#test

上面的查询使用InMemory假脱机并且非常快,但输出不是我想要的..下面是输出

datee       summ
2016-11-09  2
2016-11-09  4
2016-11-10  5
2016-11-10  6

与Disk spool相比,InMemoryspool的速度非常快。这里记录了这一点:Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions (Developer Reference)

所以我的问题是:
我如何使用InMemory Spool并获得我想要的结果。我尝试了各种框架选项,但我没有得到理想的结果

测试数据:

create table #test
(
salesorder int,
datee date
)
go

insert into #test
select 1,getdate()-1
go 2


insert into #test
select 2,getdate()-2
go 2

注意:
行选项将起作用,如果我没有重复日期,但我的数据设置是这样的,我有数千条记录,如样本

更新
这是一个大型查询的一部分,所以我更喜欢窗口函数(没有CTE或派生表)来避免重写

2 个答案:

答案 0 :(得分:1)

select distinct T1.dattee,X.Summ from SalesTab T1
    CROSS APPLY (SELECT SUM(T2.SalesOrder) SUMM FROM SalesTab T2 WHERE T2.dattee<=T1.dattee) X
    ORDER BY T1.Dattee

答案 1 :(得分:1)

如何使用它:

SELECT  datee, 
        sum(salesorder) over 
            ( order by datee rows between  unbounded preceding and  current row )
FROM (
      SELECT datee,
             sum(salesorder) as salesorder
      from #test
      GROUP BY datee
     ) t

这给出了以下内容:

  

表'工作台'。扫描计数0,逻辑读取0,物理读取0,   预读读取0,lob逻辑读取0,lob物理读取0,lob   预读读取0.表   '#TEST _______________________________________________________________________________________________________________ 0000000000A3'。扫描计数1,逻辑读取1,物理读取0,预读读取0,   lob逻辑读取0,lob物理读取0,lob预读读取0。

编辑:

  

如果您不想使用此技术,请尝试使用此变体   你自己的查询用Row_NUMBER()包装它,仍然使用IN Memeory:

SELECT datee, salesorder
FROM (
      SELECT datee, salesorder, 
             ROW_NUMBER() OVER (PARTITION BY datee ORDER BY salesorder DESC) AS RN
      FROM (
              SELECT  datee,
                      sum(salesorder) over ( order by datee rows between  unbounded preceding and  current row ) As salesorder
              FROM #test
          ) t1
  ) t2
WHERE RN = 1