Calcul de la valeur en utilisant la valeur précédente d'une ligne dans T-SQL

J'ai la table suivante et je veux calculer la valeur de la colonne 2 sur chaque ligne en utilisant la valeur de la même colonne (colonne 2) de la ligne précédente dans un sql sans utiliser le slider ou la boucle while.

Id Date Column1 Column2 1 01/01/2011 5 5 => Same as Column1 2 02/01/2011 2 18 => (1 + (value of Column2 from the previous row)) * (1 + (Value of Column1 from the current row)) ie (1+5)*(1+2) 3 03/01/2011 3 76 => (1+18)*(1+3) = 19*4 and so on 

Des pensées?


En supposant au less SQL Server 2005 pour le CTE récursif :

 ;with cteCalculation as ( select t.Id, t.Date, t.Column1, t.Column1 as Column2 from YourTable t where t.Id = 1 union all select t.Id, t.Date, t.Column1, (1+t.Column1)*(1+c.Column2) as Column2 from YourTable t inner join cteCalculation c on t.Id-1 = c.id ) select c.Id, c.Date, c.Column1, c.Column2 from cteCalculation c 

J'ai résolu le problème, juste mentionné.

C'est mon code:

 ;with cteCalculation as ( select t.Id, t.Column1, t.Column1 as Column2 from table_1 t where t.Id = 1 union all select t.Id, t.Column1, (1+t.Column1)*(1+c.Column2) as Column2 from table_1 t inner join cteCalculation c on t.Id-1 = c.id ), cte2 as( select t.Id, t.Column1 as Column3 from table_1 t where t.Id = 1 union all select t.Id, (select column2+1 from cteCalculation c where c.id = t.id) as Column3 from table_1 t inner join cte2 c2 on t.Id-1 = c2.id ) select c.Id, c.Column1, c.Column2, c2.column3 from cteCalculation c inner join cte2 c2 on c.id = c2.id 

Le résultat est comme attendu:

 1 5 5 5 2 2 18 19 3 3 76 77 

Voici un exemple utilisant ROW_NUMBER () si les ID ne sont pas nécessairement dans l'ordre:

 ;with DataRaw as ( select 1 as Id, '01/01/11' as Date, 5 as Column1 union select 2 as Id, '02/01/11' as Date, 2 as Column1 union select 4 as Id, '03/01/11' as Date, 3 as Column1 ), Data as ( select RowId = ROW_NUMBER() over (order by Id), Id, Date, Column1 from DataRaw ), Data2 as ( select RowId, id, Date, Column1, Column1 as Column2 from Data d where RowId = 1 union all select d1.RowId, d1.id, d1.Date, d1.Column1, (1+d1.column1)*(1+d2.column2) as column2 from Data d1 cross join Data2 d2 where d2.RowId + 1 = d1.RowId ) select Id, Date, Column1, Column2 from Data2 

edit: shoudld aurait mieux lu la question …

Un autre coup serait ceci:

 ;with DataRaw as ( select 1 as Id, '01/01/11' as Date, 5 as Column1 union select 2 as Id, '02/01/11' as Date, 2 as Column1 union select 4 as Id, '03/01/11' as Date, 3 as Column1 ), Data as ( select Ord = ROW_NUMBER() over (order by Id), Id, Date, Column1 from DataRaw ), select -- formula goes here, using current and prev as datasources. from data current left join data prev on current.Ord = prev.Ord + 1 -- pick the previous row by adding 1 to the ordinal 

Je pense qu'une jointure normale pour atteindre la rangée précédente serait plus rapide qu'une CTE. Vous devez vérifier par vous-même si.

Ça m'a l'air plus facile.

Bonne chance, GJ