1

作为批处理的一部分,我正在尝试在多个发票交易中实现付款分配。发票和付款交易保存在同一张表中,充当交易登记簿。

所以例如。我们的交易登记表中有:

ID,   USER ,  TYPE     , AMOUNT   
1     Mr. X   Invoice      1000   
2     Mr. X   Invoice      2000   
3     Mr. X   Invoice      1000   
4     Mr. X   Payment     -3000   
5     Mr. X   Payment      -500   

我正在寻找一个查询,该查询将为该用户支付 3500 的总付款,从第一张发票开始,将付款分配到每张发票并将其转储到新表中。

新表的最终结果如下。

ID    User ,  TYPE     ,   AMOUNT   , AMOUNT_PAID
1     Mr. X   Invoice        1000            1000
2     Mr. X   Invoice        2000            2000
3     Mr. X   Invoice        1000            500

我试图避免在 PL/SQL 块中使用循环。任何意见都非常感谢!

4

1 回答 1

4

所以这个解决方案使用了两个解析函数。在内部查询中,它使用分析 SUM() 来跟踪发票金额的滚动总计。在外部查询中,当支付的总金额不足时,它使用 LAG() 来获取先前的发票总和。

select id
       , username
       , amount
       , case when tot_amount >= rolling_pay
              then amount
         else
              tot_amount - lag(rolling_pay) over (order by id)
         end as amount_paid
from (
   with inv as (select id
                         , username
                         , amount 
                 from transactions
                 where type = 'Invoice' )
         , pay as ( select username
                            , abs(sum(amount)) as tot_amount 
                 from transactions
                 where type = 'Payment'
                 group by username )
    select inv.id
           , inv.username
           , inv.amount
           , pay.tot_amount
           , sum(inv.amount) over (partition by inv.username order by inv.id) as rolling_pay
    from inv join pay 
         on inv.username = pay.username
    order by inv.username, inv.id
  )

注意:当每个业务密钥超过一个时,我将付款相加。

这是不可避免的 SQL Fiddle,它证明了这会产生所需的结果。

于 2014-06-26T20:13:33.257 回答