Postgresql,更新多行并使用条件

时间:2015-10-09 07:25:02

标签: database postgresql conditional-statements

我的表invoice看起来像这样:
enter image description here

我有2000美元的金额,我想逐一减少这些发票,当金额结束时,我希望查询停止如下:
invoice with id = 2 --> 1500 < 2000 --> so the paid_money becomes 0
其余的金额是:2000 - 1500 = 500(仍然> 0,所以我们继续下一张发票)
invoice with id = 1 -->1500.2 > 500 --> so the paid_money becomes 1500.2 - 500 = 1000.2
剩余的金额= 0 (这是我想停止更新查询的条件)
更新顺序为ORDER BY id DESC 并且thnx为您提供帮助。

2 个答案:

答案 0 :(得分:1)

首先,我怀疑可以使用单个SQL命令来完成,因为需要特定的顺序。您应该编写PL / pgSQL过程以按顺序迭代行,每行执行逻辑和修改并在适当的时刻终止执行。

答案 1 :(得分:0)

有很多方法可以做到这一点。这是一个单个sql(没有创建任何函数或过程):

-- creates the invoice table for testing
drop table if exists invoice;
create table invoice (id integer primary key, value numeric, paid_value numeric, money_remaining numeric);
-- inserts invoices data
insert into invoice  (id, value, paid_value, money_remaining) values (1, 500, 0, 0), (2, 700, 0, 0), (3, 1000, 0, 0); 

with 
-- computes the total of money necessary to pay all invoices including the current one
-- acc_value = sum of all invoices where id is less or equals to the current invoice
a as 
(
select  i.id, i.value, (select sum(value) from invoice i1 where i1.id <= i.id) acc_value
from    invoice i
),

-- computes the total of money spent
b as 
(
select  *, (2000 - acc_value) as money_remaining
         , case when (2000 - acc_value) >= 0 then value else 0 end as paid_value
from    a
)

-- updates each invoice with it's computed values
update invoice i
   set paid_value = b.paid_value,
       money_remaining = case when b.money_remaining < 0 then (i.value + b.money_remaining) else b.money_remaining end
from b
where i.id = b.id;

-- shows the result
select * from invoice;