我正在尝试生成债务人的年龄平衡,但是当我必须考虑余额历史记录时,我正在使用MySQL SUM。
我可以通过以下方式获得客户的当前余额:
SELECT SUM(balance) FROM `transaction` WHERE customer_id = 1
起初我想获得旧的平衡 - 即。平衡如何看2011-08-31我认为以下就足够了:
SELECT SUM(balance) FROM `transaction` WHERE customer_id = 1 AND posted <= '2011-08-31'
但上述情况并未考虑自2011-09-01以来至今所发生的任何平衡历史记录。我已将所有平衡历史存储在表格中。因此,如果客户(部分)支付2011-09-06的账单,那么表格将如下所示:
交易:
id | text | amount | balance | posted
1 | Invoice | 100.00 | 20.00 | 2011-08-14
2 | Payment | 80.00 | 0.00 | 2011-09-06
余额历史记录:
id | source | destination | amount | created
1 | 1 | 2 | 80.00 | 2011-09-06
我以为我已经用以下查询解决了它:
SELECT customer_id, SUM(balance)+SUM(IFNULL(bh_source.amount, 0))-SUM(IFNULL(bh_destination.amount, 0)) AS `current_balance`
FROM `transaction`
LEFT JOIN balancehistory AS bh_source ON `transaction`.id = bh_source.source AND DATE(bh_source.created) > "2011-08-31"
LEFT JOIN balancehistory AS bh_destination ON `transaction`.id = bh_destination.destination AND DATE(bh_destination.created) > "2011-08-31"
WHERE posted <= "2011-08-31"
GROUP BY customer_id
但是当平衡历史变得更加复杂时,即。如下所示 - 它失败了:
交易:
id | text | amount | balance | posted
1 | Invoice | 100.00 | 0.00 | 2011-08-14
2 | Payment | -80.00 | 0.00 | 2011-09-06
3 | Payment cancelled | 80.00 | 0.00 | 2011-09-08
4 | VISA | -100.00 | 0.00 | 2011-10-10
余额历史记录:
id | source | destination | amount | created
1 | 1 | 2 | 80.00 | 2011-09-06
2 | 2 | 1 | -80.00 | 2011-09-08
3 | 3 | 2 | 80.00 | 2011-09-08
4 | 1 | 4 | -100.00 | 2011-10-10
我已经在墙上撞了很长时间了,希望你们有一些建议。表格结构未被锁定,因此如果需要,可以更改。
感谢。
更新
我现在看到我已经过多地简化了我的问题 - 但无论如何,谢谢汤姆。 我不是(仅)对当前总数感兴趣,而是想根据截止日期对金额进行分组。我正在尝试创建一个表格,显示应付款项的金额。 IE浏览器。 0-30天,30-90天等:
年龄平衡(使用以下数据的不同参考日期的多个SQL结果):
reference | before due | 0-30 days | 30-90 days
2011-08-31 | 233.79 | 0.00 | 0.00
2011-09-02 | 0.00 | 0.00 | 0.00
2011-09-07 | 0.00 | 233.79 | 0.00
2011-10-18 | 100.00 | 0.00 | 233.79
2011-10-25 | 0.00 | 100.00 | 233.79
2011-10-28 | 0.00 | 0.00 | 0.00
交易:
id | customer_id | text | amount | balance | posted | due
1 | 1 | Invoice 1 | 233.79 | 0.00 | 2011-08-17 | 2011-09-01
2 | 1 | Payment 1 | -233.79 | 0.00 | 2011-09-01 | 2011-09-01
3 | 1 | Payment rejected | 233.79 | 0.00 | 2011-09-06 | 2011-09-06
4 | 1 | Reminder | 100.00 | 0.00 | 2011-09-14 | 2011-09-23
5 | 1 | Payment 2 | -333.79 | 0.00 | 2011-09-23 | 2011-09-23
余额历史记录:
id | source | destination | amount | created
1 | 1 | 2 | 233.79 | 2011-09-05
2 | 2 | 1 | 233.79 | 2011-09-09
3 | 3 | 2 | 233.79 | 2011-09-09
4 | 1 | 5 | 233.79 | 2011-10-26
5 | 4 | 5 | 100.00 | 2011-10-26
以下是我认为可以找到特定日期的年龄平衡的SQL示例:
SELECT SUM(IF("2011-08-31" <= due, balance, 0))
+ SUM(IF("2011-08-31" <= due, IFNULL(bh_source.amount, 0), 0))
- SUM(IF("2011-08-31" <= due, IFNULL(bh_destination.amount, 0), 0)) AS before_due,
SUM(IF("2011-08-31" > DATE(ADDDATE(due, INTERVAL 0 DAY)) AND
"2011-08-31" <= DATE(ADDDATE(due, INTERVAL 30 DAY)), balance, 0))
+ SUM(IF("2011-08-31" > DATE(ADDDATE(due, INTERVAL 0 DAY)) AND
"2011-08-31" <= DATE(ADDDATE(due, INTERVAL 30 DAY)), IFNULL(bh_source.amount, 0), 0))
- SUM(IF("2011-08-31" > DATE(ADDDATE(due, INTERVAL 0 DAY)) AND
"2011-08-31" <= DATE(ADDDATE(due, INTERVAL 30 DAY)), IFNULL(bh_destination.amount, 0), 0)) AS 0_30_days,
SUM(IF("2011-08-31" > DATE(ADDDATE(due, INTERVAL 30 DAY)) AND
"2011-08-31" <= DATE(ADDDATE(due, INTERVAL 90 DAY)), balance, 0))
+ SUM(IF("2011-08-31" > DATE(ADDDATE(due, INTERVAL 30 DAY)) AND
"2011-08-31" <= DATE(ADDDATE(due, INTERVAL 90 DAY)), IFNULL(bh_source.amount, 0), 0))
- SUM(IF("2011-08-31" > DATE(ADDDATE(due, INTERVAL 30 DAY)) AND
"2011-08-31" <= DATE(ADDDATE(due, INTERVAL 90 DAY)), IFNULL(bh_destination.amount, 0), 0)) AS 30_90_days
FROM `transaction`
LEFT JOIN balancehistory AS bh_source ON `transaction`.id = bh_source.source AND DATE(bh_source.created) > "2011-08-31"
LEFT JOIN balancehistory AS bh_destination ON `transaction`.id = bh_destination.destination AND DATE(bh_destination.created) > "2011-08-31"
WHERE posted <= "2011-08-31"
GROUP BY customer_id
但它没有按预期工作。任何帮助/建议将不胜感激。
答案 0 :(得分:0)
如果将发票和付款交易分成两个单独的表,您可能会有更多的乐趣。例如:
invoice
id | customer_id | invoice_description | amount | postedOn
1 | 1 | Services Invoice | 100.00 | 2011-08-14 12:35:01
payment
id | customer_id | invoice_id | payment_type | amount | madeOn
1 | 1 | 1 | Payment | -80.00 | 2011-09-08 08:09:12
1 | 1 | 1 | Payment Cancelled | 80.00 | 2011-09-08 08:12:34
1 | 1 | 1 | VISA Payment | -100.00 | 2011-10-10 17:22:54
然后,您应该能够在任何时间点获得给定客户的当前余额,方法是获取截至该时间点发给他们的所有发票的总和,并减去截至该时间点收到的付款。相同的发票。因此:
select customer_id,sum(invoice_balance) as totalBalance
from
(
select i.customer_id, i.id as invoice_id,
i.amount - sum(ifnull(p.amount,0)) as invoice_balance
from invoice i
left join (select p.invoice_id,p.amount from payment where p.madeOn > '2011-09-01') p
on p.invoice_id = i.id
where i.postedOn > '2011-09-01'
group by i.customer_id, i.id, i.amount
) t group by customer_id;
我故意省略了customer_id上的联接,因为我认为不可能(但不大可能)由不同的客户向最初签发发票的客户付款。进一步考虑,您可能希望将支付表上的payment_type列标准化为paymentType表或类似的东西。