有没有一种方法可以减少postgres中的余额减去?

时间:2019-12-09 08:33:27

标签: sql postgresql

我有一个postgres查询,该查询返回的表如下所示:

_______________________________________________________
|  id  |  item  |  amount  |  paid  |  apply_payment  |
+------+--------+----------+--------+-----------------+
|  1   | item 1 |     500  |     0  |     15,000      |
|  2   | item 2 |  20,000  |  3000  |     15,000      |
|  3   | item 3 |   7,000  |     0  |     15,000      |
-------------------------------------------------------

根据上表,“客户”向购买的商品付款,在这种情况下,为15,000付款。我想对15,000的减少余额进行扣减,以便:

  • 在第一项上,15,000支付了item 1的整个500,剩下的余额为14,500
  • 在费用为item 2的{​​{1}}上,先前有20,000的付款,因此上述3000进入此处的14,500余额。
  • 17,000仍未付款,因为上面没有余额。

总而言之,结果可能看起来像这样:

item 3

如何在postgres中实现以上__________________________________________________________________________ | id | item | amount | paid | apply_payment | amount_applied | +------+--------+----------+--------+-----------------+------------------+ | 1 | item 1 | 500 | 0 | 15,000 | 500 | | 2 | item 2 | 20,000 | 3000 | 14,500 | 14,500 | | 3 | item 3 | 7,000 | 0 | 0 | 0 | -------------------------------------------------------------------------- 请注意,第二个(所需)表中的amount_applied正在减小

1 个答案:

答案 0 :(得分:1)

对于每一行,您需要从第一行到上一行在窗口上进行一些聚合(我假设顺序是由ID决定的):

with t (id, item, amount, paid, apply_payment) as (
  select 1, 'item 1',   500,    0, 15000 union
  select 2, 'item 2', 20000, 3000, 15000 union
  select 3, 'item 3',  7000,    0, 15000
)
select id, item, amount, paid, apply_payment, amount - paid as really_remaining,
  greatest(apply_payment - coalesce(sum (amount - paid) over (order by id rows between unbounded preceding and 1 preceding), 0), 0) as cash_before_this_row,
  least(amount - paid, greatest(apply_payment - coalesce(sum (amount - paid) over (order by id rows between unbounded preceding and 1 preceding), 0), 0)) amount_applied
from t
order by id;

(我将apply_payment列重命名为cash_before_this_row,因为在源表中使用了名称apply_payment,但结果含义不同。)