过去12个月的总计表,按月和按月计算

时间:2017-03-30 10:50:11

标签: sql sql-server

我希望有一个包含12行的表,过去12个月中每一行都有一行,另外还有两列:

  • 那个月(也就是那个月的总花费)
  • 自开始以来的总支出

表格如下:

Month   MonthTotal      RunningTotal
Apr 16  0               6710
May 16  0               6710
Jun 16  2000            8710
Jul 16  0               8710
Aug 16  0               8710
Sep 16  0               8710
Oct 16  1000            9710
Nov 16  0               9710
Dec 16  0               9710
Jan 17  500             10210
Feb 17  0               10210
Mar 17  0               10210

我几乎就在那里,但是当我有几个月没有购买时,我遇到了一个问题 - 该列输出为空。这是我当前的疑问:

with Y(n) as
(
    select 0
    union all
    select n + 1 
    from Y
    where n < 11
)

select
    convert(varchar, M.Month) + '/' + convert(varchar, M.Year % 100) as Month,
    isnull(sum(A.Value), 0) as MonthAssetValue,
    sum(A.Value) over (order by A.DateAquired rows between unbounded preceding and current row) as TotalAssetValue

from (
    select
        datepart(year, dateadd(month, -n, getdate())) as [Year],
        datepart(month, dateadd(month, -n, getdate())) as [Month]

    from
        Y
) M

left outer join Asset A
    on (datepart(year, A.DateAquired) = M.Year and datepart(month, A.DateAquired) = M.Month)


group by
    M.Year,
    M.Month,
    A.DateAquired,
    A.Value

order by
    M.Year,
    M.Month

我出错的任何想法?

修改

这是我目前获得的输出:

Month   MonthTotal      RunningTotal
Apr 16  0               null            
May 16  0               null            
Jun 16  2000            8710
Jul 16  0               null            
Aug 16  0               null            
Sep 16  0               null            
Oct 16  1000            9710
Nov 16  0               null            
Dec 16  0               null            
Jan 17  500             10210
Feb 17  0               null            
Mar 17  0               null            

3 个答案:

答案 0 :(得分:0)

您可以使用滚动窗口功能

SELECT Month, MonthTotal, [Sum 12 Months] = SUM(MonthTotal) OVER (ORDER BY [Month] ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) 
    FROM YourTable

答案 1 :(得分:0)

您的问题是group by。它应该只有年和月:

group by M.Year, M.Month

此外,请勿使用varchar()一段时间。而且,我认为windows函数调用中存在语法错误。您需要混合聚合和窗口函数。

我会将查询写成:

with Y(n) as (
      select 0
      union all
      select n + 1 
      from Y
      where n < 11
     )
select left(m.mmm, 3) + '/' + right(yyyymm.yyyy, 2) as mmmyy,
       coalesce(sum(A.Value), 0) as MonthAssetValue,
       sum(coalesce(sum(A.Value), 0)) over (order by min(dte)) as TotalAssetValue
from (select datename(year, dateadd(month, -n, getdate())) as yyyy,
             datename(month, dateadd(month, -n, getdate())) as mmm,
             dateadd(month, -n, getdate()) as dte
      from Y
     ) yyyymm left outer join
     Asset A
     on datename(year, A.DateAquired) = yyyymm.yyyy and
        datename(month, A.DateAquired) = yyyymm.mmm
group by yyyymm.yyyy, yyyymm.mmm
order by min(dte);

实际上,老实说,我会将年/月表示为YYYY-MM,但我保留了你的格式。

答案 2 :(得分:-1)

尝试将sum(A.Value)替换为MonthAssetValue,     sum(A.Value)over(由A.DateAquired排序)无界前行和当前行之间的行)作为TotalAssetValue

以下

SUM(COALESCE(A.Value,0))作为MonthAssetValue,

SUM(COALESCE(A.Value,0))over(无限制的前一行和当前行之间的行)(作为A.DateAquired))作为TotalAssetValue