If your indexes don't have spaces, the easiest solution would be
- Create a recursive
CTE
, starting with the value, to subtract and reduce it in the recursive part. - Use
CTE
Results to Update Actual Table
SQL statement
;WITH q AS ( SELECT idx, amount, balance, 130 AS Deduct FROM tbl1 WHERE idx = 1 UNION ALL SELECT t.idx, t.amount, t.balance, q.Deduct - q.balance FROM q INNER JOIN @tbl1 t ON t.idx = q.idx + 1 WHERE q.Deduct - q.balance > 0 ) UPDATE @tbl1 SET Balance = CASE WHEN q.Balance - q.Deduct > 0 THEN q.Balance - q.Deduct ELSE 0 END FROM q INNER JOIN tbl1 t ON t.idx = q.idx
Using ROW_NUMBER
, you can fix the problem with a space, but this complicates the request a bit.
;WITH r AS ( SELECT idx, amount, balance, rn = ROW_NUMBER() OVER (ORDER BY idx) FROM tbl1 ), q AS ( SELECT rn, amount, balance, 130 AS Deduct, idx FROM r WHERE rn = 1 UNION ALL SELECT r.rn, r.amount, r.balance, q.Deduct - q.balance, r.idx FROM q INNER JOIN r ON r.rn = q.rn + 1 WHERE q.Deduct - q.balance > 0 ) UPDATE tbl1 SET Balance = CASE WHEN q.Balance - q.Deduct > 0 THEN q.Balance - q.Deduct ELSE 0 END FROM q INNER JOIN @tbl1 t ON t.idx = q.idx
Test script
DECLARE @tbl1 TABLE (idx INTEGER, Amount INTEGER, Balance INTEGER) INSERT INTO @tbl1 (idx,amount,balance) VALUES (1, 50, 50) INSERT INTO @tbl1 (idx,amount,balance) VALUES (2, 30, 30) INSERT INTO @tbl1 (idx,amount,balance) VALUES (3, 20, 20) INSERT INTO @tbl1 (idx,amount,balance) VALUES (4, 50, 50) INSERT INTO @tbl1 (idx,amount,balance) VALUES (5, 60, 60) ;WITH q AS ( SELECT idx, amount, balance, 130 AS Deduct FROM @tbl1 WHERE idx = 1 UNION ALL SELECT t.idx, t.amount, t.balance, q.Deduct - q.balance FROM q INNER JOIN @tbl1 t ON t.idx = q.idx + 1 WHERE q.Deduct - q.balance > 0 ) UPDATE @tbl1 SET Balance = CASE WHEN q.Balance - q.Deduct > 0 THEN q.Balance - q.Deduct ELSE 0 END FROM q INNER JOIN @tbl1 t ON t.idx = q.idx SELECT * FROM @tbl1
Exit
idx Amount Balance 1 50 0 2 30 0 3 20 0 4 50 20 5 60 60