Supposons que j'ai une table SQL de récompenses, avec des champs pour la date et le montant. J'ai besoin de générer une table avec une séquence de dates consécutives, le montant accordé chaque jour et le total cumulé.Améliorer la requête SQL: montants cumulés au fil du temps
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
Ce SQL fonctionne, mais pas aussi vite que je le voudrais:
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)
J'ai essayé d'ajouter un index Awards.Date, mais il a fait une différence très minime. Avant de recourir à d'autres stratégies comme la mise en cache, existe-t-il un moyen plus efficace de coder le calcul du total cumulatif?
Merci beaucoup - c'est parfait. Incroyable à quelle vitesse c'est. –
Je n'ai jamais vu de syntaxe comme "SET @x = a = @x + b" auparavant. Pour quel RDBMSes cela fonctionne-t-il? – MatBailie
@Dems: Cette syntaxe est pour SQL Server, mais vous pouvez faire quelque chose de très similaire dans mysql (voir le lien au bas de ma réponse - où quelqu'un a posté une version mysql). – Aaronaught