我需要一种更快的方法来计算和显示运行总和。
这是一个MVC telerik网格,它使用子查询查询生成运行总和的视图。查询需要73秒才能完成,这是不可接受的。 (每次用户点击“刷新预测表”时,重新填充网格需要73秒。)
查询如下所示:
SELECT outside.EffectiveDate
[omitted for clarity]
,(
SELECT SUM(b.Amount)
FROM vCI_UNIONALL inside
WHERE inside.EffectiveDate <= outside.EffectiveDate
) AS RunningBalance
[omitted for clarity]
FROM vCI_UNIONALL outside
某些项目的“EffectiveDate”可以随时更改......可以添加新项目等等。我当然需要能够动态计算运行总和的东西(当点击“刷新”按钮时)。存储过程或另一个视图...?请指教。
解决方案:(其中一个,这个比子查询快几个数量级)
创建一个包含视图中除RunningTotal
col 之外的所有列的新表。创建一个首先截断表的存储过程,然后使用INSERT INTO
所有列SELECT
表,而不运行总和列。
使用更新局部变量方法:
DECLARE @Amount DECIMAL(18,4)
SET @Amount = 0
UPDATE TABLE_YOU_JUST_CREATED SET RunningTotal = @Amount, @Amount = @Amount + ISNULL(Amount,0)
创建一个每天运行一次存储过程的任务代理。将TABLE_YOU_JUST_CREATED
用于所有报告。
答案 0 :(得分:1)
看一下这篇文章 Calculate a Running Total in SQL Server
如果您有SQL Server Denali,则可以使用新的窗口函数。
在SQL Server 2008 R2中,我建议您使用递归公用表表达式。 CTE中的一个小问题是,对于快速查询,您必须具有无间隙的标识列(1,2,3,...),如果您没有这样的列,则必须创建具有此类列的临时或变量表。列,并将您的数据移动到那里。
CTE方法将是这样的
declare @Temp_Numbers (RowNum int, Amount <your type>, EffectiveDate datetime)
insert into @Temp_Numbers (RowNum, Amount, EffectiveDate)
select row_number() over (order by EffectiveDate), Amount, EffectiveDate
from vCI_UNIONALL
-- you can also use identity
-- declare @Temp_Numbers (RowNum int identity(1, 1), Amount <your type>, EffectiveDate datetime)
-- insert into @Temp_Numbers (Amount, EffectiveDate)
-- select Amount, EffectiveDate
-- from vCI_UNIONALL
-- order by EffectiveDate
;with
CTE_RunningTotal
as
(
select T.RowNum, T.EffectiveDate, T.Amount as Total_Amount
from @Temp_Numbers as T
where T.RowNum = 1
union all
select T.RowNum, T.EffectiveDate, T.Amount + C.Total_Amount as Total_Amount
from CTE_RunningTotal as C
inner join @Temp_Numbers as T on T.RowNum = C.RowNum + 1
)
select C.RowNum, C.EffectiveDate, C.Total_Amount
from CTE_RunningTotal as C
option (maxrecursion 0)
可能存在重复EffectiveDate
值的一些问题,这取决于您希望如何使用它们 - 您是希望它们是任意订购还是您希望它们具有相等金额?< / p>