Обновите таблицу после вычисления суммы на основе нескольких записей из другой таблицы

#sql #oracle

#sql #Oracle

Вопрос:

У меня есть две таблицы, одна из которых является Base_table, а другая — Txn_table следующим образом

Base_table

 Person  | Amount
----------------
P1        300
p2        200   
p3        100
  

Txn_table

 Person  |  txn_type  |  Amount
---------------------------------
P1        Debit         200    
P2        Credit        200    
P3        Debit         100    
P1        Credit        400
  

Мне нужно обновить базовую таблицу на основе данных Txn_table, например, P1 выполнил дебетование и кредит, общий расчет примерно такой (Credit-Debit) = (400-200) = 200, и у P1 уже есть 300 в базовой таблице, поэтому общее значение 300 200 = 500 необходимо обновить в базовой таблице для P1.in таким же образом и для других, пожалуйста, помогите мне написать запрос Oracle SQL

И данные должны быть такими в Base_table после обновления.

Base_table

 Person  | Amount    
P1        500    
p2        400    
p3        0
  

Примечание: здесь я не должен использовать блок PLsql, только мне нужно выполнить это обновление с помощью SQL-запроса.

Ответ №1:

Встроенный коррелированный подзапрос может выполнить задание:

 UPDATE base_table b
SET b.amount =
    b.amount 
      NVL(
        (SELECT SUM(DECODE(t.txn_type, 'Credit', 1, -1) * t.amount)
        FROM txn_table t
        WHERE t.person = b.person
    ), 0)
  

Ответ №2:

В Oracle типичным способом обновления одной таблицы из другой является использование коррелированных подзапросов:

 update base_table b
    set amount = b.amount  
                 (select sum(case when t.txn_type = 'Credit' then t.amount else - t.amount end)
                  from txn_table t
                  where t.person = b.person
                 )
    where exists (select 1
                  from txn_table t
                  where t.person = b.person
                  having sum(case when t.txn_type = 'Credit' then t.amount else - t.amount end) <> 0
                 );
  

Ответ №3:

Просто чтобы предложить другой подход.

 merge into base_table tt
    using
    ( select person , sum( decode(upper(txn_type) ,
                               'CREDIT',   AMOUNT ,
                               'DEBIT', - AMOUNT
                             ) ) as final
                            from Txn_table
                  group by person  ) b
    on ( tt.person = b.person )
    when matched then
    update  set tt.AMOUNT =  tt.AMOUNT   b.final