【问题标题】:How to retrieve unpaid amount of each invoice for finance charges?如何检索财务费用每张发票的未付金额?
【发布时间】:2019-06-08 11:00:48
【问题描述】:

我正在实施财务费用,但不知道如何检索每张发票的未付金额。我对 SQL 并不陌生,但是这个问题让我很困惑。如果我没有正确搜索,请原谅我。

所以,假设我有一张发票表:

 id | amount   
----+--------------
 1  | 50.00         
 2  | 50.00      
 3  | 50.00     
 4  | 50.00    
 5  | 50.00

还有一张付款表:

amount   
--------------
50.00       
25.00   

结果集应该是这样的:

 invoice_id | unpaid_amount   
------------+--------------       
 2          | 25.00      
 3          | 50.00     
 4          | 50.00     
 5          | 50.00 

当然,要实施财务收费还有很多东西要添加,但我想我可以得到其余的。

编辑:对不起,我的疏忽。 id 不相关。删除了付款 ID 列。

编辑 2:这些是虚构的数字,现实生活中的数字可以是任何数字,因此无法对数量进行匹配。

编辑 3: 在这里我创建了一个 SQL Fiddle 来展示我到目前为止所拥有的,基于 @GordonLinoff 第二个答案。我希望有一种比我编写的笨拙的 SQL 更简洁的方法。

【问题讨论】:

  • 表之间是什么关系? ids 是否相关?
  • @GordonLinoff 没有 ID 不相关。
  • 如果表之间没有定义的关系,是否还有其他可用于确定处理顺序的东西,比如日期?
  • @Belayer 是的,对于处理顺序,有一个日期(初级排序)和一个id(二级排序)。我有一个基于 GordonLinoff 第二个答案的部分解决方案,但它看起来很可怕。我将非常感谢一个干净的好 SQL。
  • 这是一个非常糟糕的数据模型。您的付款表缺少发票表的外键。如果您在同一天开具两张发票怎么办?那么您就无法将付款正确链接到发票。

标签: sql postgresql invoice


【解决方案1】:

我想你想要一个join:

select i.id as invoice_id,
       (i.amount - coalesce(p.amount, 0)) as net_amount
from invoice i left join
     payment p
     on i.id = p.id;

编辑:

或者,您可能想要:

select i.*,
       (case when sum(i.amount) over (order by i.id) < p.amount 
             then i.amount
             else greatest(p.amount - sum(i.amount) over (order by i.id) + i.amount, 0)
        end) as amount_paid
from invoice i cross join
     (select sum(amount) as amount
      from payment
     ) p;

Here 是一个 dbfiddle。

【讨论】:

  • 谢谢。你能检查我的SQL Fiddle 以了解可能的改进吗?看起来真的很粗糙。
  • @theGtknerd 。 . .小提琴真的很有帮助。我修复了逻辑,您可以在小提琴中看到结果。请注意,这是针对amount_paid 而不是amount_unpaid
【解决方案2】:

您可以使用LEFT JOIN 并从两个表中减去金额。 COALSECE 在这里是为了防止您在没有付款时获得NULL

select
     i.id as invoice_id
    ,i.amount - coalesce(p.amount,0) as amount
from invoice i 
left join payments p
    on p.id = i.id

如果在您的payments 列表中可以为一张发票支付多笔付款,您应该先将payments 分组,然后再将其加入invoice

select
     i.id as invoice_id
    ,i.amount - coalesce(p.amount,0) as amount
from invoice i 
left join (select id, sum(amount) as amount  from payments group by id) p
    on p.id = i.id

【讨论】:

    猜你喜欢
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2014-11-16
    • 2016-11-18
    相关资源
    最近更新 更多