表1帐单
| bill_id| date | supplier_id |amount|
| 101 | 2019-03-16| 1570 |1000 |
| 102 | 2019-05-20| 1570 |2500 |
表2付款
| bill_id| date | paid|
| 101 | 2019-03-17 | 800 |
| 101 | 2019-05-20 | 150 |
预期结果
| supplier_id |bill_id |amount|Paid | Balance|
| 1570 | 101 |1000 | 950 | 50 |
| 1570 | 102 |2500 | 0 | 2500 |
我该如何实现
答案 0 :(得分:1)
我会预先汇总payment
SELECT p.bill_id
, SUM(p.amount) AS paid
FROM payment p
GROUP BY p.bill_id
然后将该查询用作内联视图...
SELECT b.supplier_id
, b.bill_id
, b.amount
, IFNULL(q.paid,0) AS paid
, b.amount - IFNULL(q.paid.0) AS balance
FROM bill b
LEFT
JOIN ( SELECT p.bill_id
, SUM(p.amount) AS paid
FROM payment p
GROUP BY p.bill_id
) q
ON q.bill_id = b.bill_id
ORDER
BY b.supplier_id
, b.bill_id
请注意,我们无法保证bill_id
表中bill
的唯一性。看起来它可能是主键,但这只是一个猜测。如果不是唯一的,则此查询的结果可能不会是我们想要的。
请注意,我们正在使用外部联接(关键字LEFT
),因此查询将返回bill
的行,其中payment
中没有匹配的行。 IFNULL
包装器是将NULL值(如果付款中没有匹配的行,我们会将其转换为零)的简便方法。