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可能在规模上具有竞争力,但在大规模情况下,它的速度可能会更快。