Sql 如果给定天数,则为月的累计总和

Sql 如果给定天数,则为月的累计总和,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我的桌子如下 T1 (date int, dateYearMonth int, userID int, shopID int, amount numeric(18,2)) 示例数据: (20151212, 201512, 1, 1, 50.00), (20151213, 201512, 1, 1, 30.00), (20160110, 201601, 1, 1, 13.00) 我想返回用户每月的累计金额, 我的问题是: select t.dateYearMonth, t.userID, su

我的桌子如下

T1 (date int, dateYearMonth int, userID int, shopID int, amount numeric(18,2))
示例数据:

(20151212, 201512, 1, 1, 50.00),
(20151213, 201512, 1, 1, 30.00),
(20160110, 201601, 1, 1, 13.00)
我想返回用户每月的累计金额, 我的问题是:

select t.dateYearMonth, t.userID,
sum(t.sum_amount) over
(partition by t.userID order by t.dateYearMonth
 rows between unbounded preceding and current row)
from (select dateYearMonth, userID, sum(amount) as sum_amount FROM T1
group by dateYearMonth, userID) t
有没有更好的方法来做到这一点? 预期产量

(201512, 1, 1, 80.00), (201601, 1, 1, 93.00)
您可以使用:

SELECT DISTINCT dateYearMonth, userID
       ,total = SUM(amount) OVER(PARTITION BY userID ORDER BY dateYearMonth)
FROM T1;

您可以使用:

SELECT DISTINCT dateYearMonth, userID
       ,total = SUM(amount) OVER(PARTITION BY userID ORDER BY dateYearMonth)
FROM T1;

我认为您的查询很好。我不认为它能做得更好

确保您有一个覆盖索引,如下所示:

CREATE NONCLUSTERED INDEX [IX] ON T1
(
    userID ASC
    ,dateYearMonth ASC
) INCLUDE(amount);
使用此索引,带有示例数据的临时表的执行计划如下所示:

CREATE NONCLUSTERED INDEX [IX] ON T1
(
    userID ASC
    ,dateYearMonth ASC
) INCLUDE(amount);


它只读取表(索引)中的所有行,并对它们进行分组/求和,而无需额外排序。

我认为您的查询很好。我不认为它能做得更好

确保您有一个覆盖索引,如下所示:

CREATE NONCLUSTERED INDEX [IX] ON T1
(
    userID ASC
    ,dateYearMonth ASC
) INCLUDE(amount);
使用此索引,带有示例数据的临时表的执行计划如下所示:

CREATE NONCLUSTERED INDEX [IX] ON T1
(
    userID ASC
    ,dateYearMonth ASC
) INCLUDE(amount);


它只读取表(索引)中的所有行,并对它们进行分组/求和,而无需额外排序。

为什么
201601的
93.00
?这是累积总和-它在几个月内不断上升(以前的值+当前值)。请尝试递归CTE,并将性能与您的方法进行比较。递归cte也应适用于早期版本的SQL Server。与分析函数(如sum()over())相比,您不太可能找到更优化的方法。递归CTE在规模上可能具有竞争力,但在大规模情况下它可能会更快。为什么
201601
93.00
?这是累积总和-它在几个月内不断上升(以前的值+当前值),请尝试递归CTE,并将性能与您的方法进行比较。递归cte也应适用于早期版本的SQL Server。与分析函数(如sum()over())相比,您不太可能找到更优化的方法。递归CTE可能在规模上具有竞争力,但在大规模情况下,它的速度可能会更快。