根据前一行的计算更新行 - SQL Server

时间:2018-04-13 18:59:56

标签: sql sql-server updating

我想更新每个id的整个表格(如图所示)。如图所示,我需要为每个user_id计算每行中列的值:

interim balance = opening_balance + Debit+ Credit 

calculated_interest = (opening_balance + Debit+ Credit) * interest_rate

closing_balance = interim balance  + calculated_interest

每行的opening_balance是前一行的closing_balance。因此,下一行的opening_balance取决于前一行的计算。

我试图使用滞后但由于前一行的计算没有完成,所有值都变为0.

这是我尝试过的代码,但它无效。

UPDATE M
SET M.closing_balance = res.closing_balance + res.Credit + res.Debit
FROM [Test].[dbo].[Main] M
JOIN
    (SELECT
         a.[User_ID], a.[calender_day],  a.[Debit], a.[Credit], 
         LAG(closing_balance, 1, (a.[opening_balance] + a.[Debit] + a.[Credit])) OVER (PARTITION BY [User_ID] ORDER BY [calender_day] ASC) AS closing_balance
     FROM 
         [Test].[dbo].[Main] a) res ON res.[User_ID] = M.User_ID
                                    AND res.[calender_day] = M.[calender_day] 

enter image description here

3 个答案:

答案 0 :(得分:0)

我怀疑这会比循环更快,但你可以通过代替LAG来做到这一点,根据前面的所有行计算每一行。

快速了解我的意思是:

OpeningBalance=(Subquery to get The First OpeningBalance for this UserID)
 + SUM(Debit) + SUM(Credit) WHERE CalendarDay < {This Row's CalendarDay}

ClosingBalance=(Subquery to get The First OpeningBalance for this UserID)
 + SUM(Debit) + SUM(Credit) WHERE CalendarDay <= {This Row's CalendarDay}

答案 1 :(得分:0)

使用user_id和calendar_day排序的记录集上的RW游标在CLR中运行更新。 CLR可以聚合并计算数据并使用单个表扫描进行更新。

答案 2 :(得分:0)

以下是我发现的问题的答案。

    FIRST_VALUE(openingbalance) OVER 
(PARTITION BY UserID ORDER BY Calendar_day ) + 
SUM(Credit - Debit) OVER 
(PARTITION BY UserID ORDER BY Calendar_day ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)