Предположим, у меня есть таблица наград SQL с полями для даты и суммы. Мне нужно создать таблицу с последовательностью последовательных дат, суммой, присуждаемой за каждый день, и промежуточным (совокупным) итогом.
Date Amount_Total Amount_RunningTotal
---------- ------------ -------------------
1/1/2010 100 100
1/2/2010 300 400
1/3/2010 0 400
1/4/2010 0 400
1/5/2010 400 800
1/6/2010 100 900
1/7/2010 500 1400
1/8/2010 300 1700
Этот SQL работает, но не так быстро, как хотелось бы:
Declare @StartDate datetime, @EndDate datetime
Select @StartDate=Min(Date), @EndDate=Max(Date) from Awards
; With
/* Returns consecutive from numbers 1 through the
number of days for which we have data */
Nbrs(n) as (
Select 1 Union All
Select 1+n
From Nbrs
Where n<=DateDiff(d,@StartDate,@EndDate)),
/* Returns all dates @StartDate to @EndDate */
AllDays as (
Select Date=DateAdd(d, n, @StartDate)
From Nbrs )
/* Returns totals for each day */
Select
d.Date,
Amount_Total = (
Select Sum(a.Amount)
From Awards a
Where a.Date=d.Date),
Amount_RunningTotal = (
Select Sum(a.Amount)
From Awards a
Where a.Date<=d.Date)
From AllDays d
Order by d.Date
Option(MAXRECURSION 1000)
Я попытался добавить индекс в Awards.Date, но это имело минимальное значение.
Прежде чем я прибегну к другим стратегиям, таким как кэширование, существует ли более эффективный способ кодирования вычисления промежуточного итога?