有几种方法可以解决您的问题。一种方法是根据F_DATE
和何时对每一行进行排名F_AMOUNT
值为零对每一行进行排名,以拉下一行由于您没有指定 SQL Server 的版本,因此我使用了适用于 SQL Server 2005 或更高版本的语法。
With RnkItems As
(
Select B_ID, P_DATE, P_AMOUNT, F_DATE, F_AMOUNT
, Row_Number() Over ( Order By F_DATE ) As Rnk
From SourceData
)
Select R.B_ID, R.P_DATE, R.P_AMOUNT
, R.F_DATE As [Original F_DATE]
, R.F_AMOUNT As [Original F_AMOUNT]
, Case R.F_AMOUNT
When 0 Then R1.F_DATE
Else R.F_DATE
End As F_DATE
, Case R.F_AMOUNT
When 0 Then R1.F_AMOUNT
Else R.F_AMOUNT
End As F_AMOUNT
From RnkItems As R
Left Join RnkItems As R1
On R1.Rnk = R.Rnk + 1
SQL小提琴版本
如果您使用的是 SQL Server 2012,则可以使用新的Lead函数:
Select B_ID, P_DATE, P_AMOUNT
, F_DATE As [Original F_DATE]
, F_AMOUNT As [Original F_AMOUNT]
, Case F_AMOUNT
When 0 Then Lead ( F_DATE, 1 ) Over ( Order By F_DATE )
Else F_DATE
End As F_DATE
, Case F_AMOUNT
When 0 Then Lead ( F_AMOUNT, 1 ) Over ( Order By F_DATE )
Else F_AMOUNT
End As F_AMOUNT
From SourceData
SQL小提琴版本
上述两种解决方案依赖于您总是提前一个月的规定要求。但是,如果您想在第一个月使用非零值(即,它可能是多次跳跃),那就不同了:
Select S.B_ID, S.P_DATE, S.P_AMOUNT
, S.F_DATE As [Original F_DATE]
, S.F_AMOUNT As [Original F_AMOUNT]
, Case S.F_AMOUNT
When 0 Then (
Select Min( S2.F_DATE )
From SourceData As S2
Where S2.F_DATE >= S.F_DATE
And S2.F_AMOUNT <> 0
)
Else S.F_DATE
End As F_DATE
, Case S.F_AMOUNT
When 0 Then (
Select S1.F_AMOUNT
From SourceData As S1
Where S1.F_DATE = (
Select Min( S2.F_DATE )
From SourceData As S2
Where S2.F_DATE > S.F_DATE
And S2.F_AMOUNT <> 0
)
)
Else S.F_AMOUNT
End As F_AMOUNT
From SourceData As S
SQL小提琴版本