Je suppose que l'ordre est défini par WeekNumber
, et que cela est séquentielle sans lacunes. Plutôt que de faire une mise à jour, pourquoi ne pas simplement effectuer les calculs au cours de sélection (cette façon, vous n'avez pas à vous soucier du calcul étant hors de date):
declare @t table (WeekNumber int, Var1 int)
insert into @t (WeekNumber, Var1) values
(1, 10),
(2, 30),
(3, 80)
;with CarryOvers as (
select WeekNumber,Var1,CONVERT(decimal(38,4),Var1) as CarryOver from @t where WeekNumber=1
union all
select t.WeekNumber,t.Var1,CONVERT(decimal(38,4),t.Var1 + (0.2*co.CarryOver))
from @t t inner join CarryOvers co on t.WeekNumber = co.WeekNumber+1
)
select * from CarryOvers option (maxrecursion 0)
Résultats:
WeekNumber Var1 CarryOver
----------- ----------- ---------------------------------------
1 10 10.0000
2 30 32.0000
3 80 86.4000
UPDATE
Version:
declare @t table (WeekNumber int, Var1 int,CarryOver decimal(38,4))
insert into @t (WeekNumber, Var1) values
(1, 10),
(2, 30),
(3, 80)
;with CarryOvers as (
select WeekNumber,Var1,CONVERT(decimal(38,4),Var1) as CarryOver from @t where WeekNumber=1
union all
select t.WeekNumber,t.Var1,CONVERT(decimal(38,4),t.Var1 + (0.2*co.CarryOver))
from @t t inner join CarryOvers co on t.WeekNumber = co.WeekNumber+1
)
update t set CarryOver = co.CarryOver
from @t t inner join CarryOvers co on t.WeekNumber = co.WeekNumber
option (maxrecursion 0)
select * from @t
Mais je le répète, je vous recommande de le faire contre à moins d'une problème de performance prouvé pour exécuter simplement le SELECT
lors d'une utilisation normale - tout autre UPDATE
s à la table maintenant besoin de ce UPDATE
être exécuté immédiatement après, de sorte que vous ajoutez un coût de performance considérable pour chaque UPDATE
.
Avec Brand
ajouté:
declare @t table (Brand char(1),WeekNumber int, Var1 int)
insert into @t (Brand,WeekNumber, Var1) values
('x',1, 10),
('x',2, 30),
('x',3, 80),
('y',1,40),
('y',2,50)
;with CarryOvers as (
select Brand,WeekNumber,Var1,CONVERT(decimal(38,4),Var1) as CarryOver from @t where WeekNumber=1
union all
select t.Brand,t.WeekNumber,t.Var1,CONVERT(decimal(38,4),t.Var1 + (0.2*co.CarryOver))
from @t t inner join CarryOvers co on t.WeekNumber = co.WeekNumber+1 and t.Brand = co.Brand
)
select * from CarryOvers
order by Brand,WeekNumber option (maxrecursion 0)
vous pouvez faire en 1ère sélection stmnt pour la dernière valeur, où u obtenir la dernière carry_over_Value puis insérez ou mettre à jour –