Обновите данные последующих строк, если первая строка была обновлена ​​в SQL - PullRequest
0 голосов
/ 08 октября 2019

Как обновить следующую строку, если данные в первой строке изменились?

Как построить правильный запрос SQL для этой ситуации?

ID ACTION ORIBALANCE TRANAMOUNT NEWBALANCE
1, Deposit, 1000, 100,1100
2,Deposit,1100,300,1400
3,Deposit,1400,500,1900
4,Withdraw,1900,-300,1600
5,Withdraw,1600,-500,1100

Если я обновлю идентификатор строки 1, я изменил значение транамонта с 100 на 500, поэтому новый баланс будет обновлен до 1500. RowID 2 обновит свой орибаланс с 1100 до 1500. Он накапливается.

Ожидаемый результат

ID ACTION ORIBALANCE TRANAMOUNT NEWBALANCE
1, Deposit, 1000, 500,1600
2,Deposit,1600,300,1900
3,Deposit,1900,500,2400
4,Withdraw,2400,-300,2100
5,Withdraw,2100,-500,1600

Ответы [ 3 ]

0 голосов
/ 08 октября 2019

Вы можете обновить его с видом рабочего процесса

-- Start updating row id = 2 for example

declare @id int = 2;
update t set TRANAMOUNT = 500
where id = @id;

-- and update following rows

declare @startb int = (select top(1) ORIBALANCE from t 
where id = @id);
with c as
(
  select id, action, ORIBALANCE, TRANAMOUNT, NEWBALANCE
    , s = @startb + sum(TRANAMOUNT) over(order by id) - TRANAMOUNT
    , n = @startb + sum(TRANAMOUNT) over(order by id)
  from t
  where id >= @id
)
update c
set ORIBALANCE = s, NEWBALANCE = n; 

Но я советую против этого, потому что обновление одной строки вызывает блокировку всей таблицы. Попробуйте создать представление для ORIBALANCE, NEWBALANCE данных.

0 голосов
/ 08 октября 2019

Если я правильно понял, вы хотите обновить каждую строку в соответствии с суммой изменения.

DECLARE @ChangeAmount INT = 500
DECLARE @ID INT = 1

UPDATE DataTable SET 
    ORIBALANCE = ORIBALANCE + ( CASE WHEN @ID > ID THEN @ChangeAmount ELSE 0 END ),
    NEWBALANCE = NEWBALANCE + @ChangeAmount
WHERE ID >= @ID
0 голосов
/ 08 октября 2019

Похоже, вам нужна кумулятивная сумма и добавление первого значения:

select ID, ACTION, TRANAMOUNT,
       (sum(TRANAMOUNT) over (order by id) -
        TRANAMOUNT +
        first_value(ORIBALANCE) over (order by id)
       ) as new_oribalance
from t;

Вы можете легко поместить это значение в update:

with toupdate as (
      select t.*
             (sum(TRANAMOUNT) over (order by id) -
              TRANAMOUNT +
              first_value(ORIBALANCE) over (order by id)
             ) as new_oribalance
      from t
     )
update toupdate
    set oribalance = new_oribalance
    where oribalance <> new_oribalance;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...