2017-08-11 28 views
1

我目前正在研究一个小型客户管理系统,并且我遇到了一个功能,我还不能在纯SQL中工作(目前使用PHP foreach的延迟加载,所以很慢)。MySQL - 按客户使用3个表格计算发票余额分组

我想获得每个客户的当前余额,因此得到每个发票的销售额(通过减少支付的总和)付款和SUM他们。每个客户在系统中都有发票,每个发票可以有多个付款。

这里是我的简单的表格为是通用的目的:

[Clients] 
- id 
- name 

[Invoices] 
- id 
- client_id 
- amount 

[Payments] 
- id 
- invoice_id 
- amount (positive number) 

所以基本上,我想这一点:

+--------------------+----------------------+ 
| name    | balance    | 
+--------------------+----------------------+ 
| Client 1   | 342,46    | 
| Client 2   | 0,00     | 
+--------------------+----------------------+ 

来获取发票卖,我需要SUM(invoices.amount) - SUM(payments.amount))但我查询根本不工作。这是我到目前为止:

SELECT DISTINCT 
    c.name, 
    SUM(x.sold) AS balance 
FROM 
    clients AS c 
RIGHT JOIN 
    (
     SELECT SUM(i.invoiceAmount - total_payments) AS sold 
     FROM invoices 
     WHERE i.client_id = c.id 
     RIGHT JOIN (
      SELECT p.id, p.invoice_id, SUM(p.transactionAmount) AS total_payments 
      FROM payments AS p 
      GROUP BY p.invoice_id 
     ) AS p ON p.invoice_id=i.id 
     GROUP BY i.client_id 
    ) AS x ON x.client_id=c.id 
GROUP BY c.name 
ORDER BY c.name ASC 

有没有人曾经这样做过?我从来没有做过,这非常棘手。

注意:我试图尽可能通用,所以它可能会帮助处于类似情况的其他人。

UPDATE: 使用@GordonLinoff答案,我能得到我想要的东西,他用我提供的查询。

select name, SUM(invoices - IFNULL(payments, 0)) as balance 
from (
    select name, sum(amount) as invoices, sum(payments) as payments 
    from (select c.id, c.name, i.id as invoiceid, i.amount, sum(p.amount) as payments 
      from clients c left join 
       invoices i 
       on c.id = i.client_id left join 
       payments p 
       on p.invoice_id = i.id 
      group by c.id, c.name, invoiceid, i.amount 
     ) ci 
    group by name 
) x 

结果与我的预期完全一致。

回答

1

通过层次结构进行聚合非常棘手。下面是连接表在一起的一个方法,然后利用聚集的两个层次:

select name, sum(amount) as invoices, sum(payments) as payments 
from (select c.id, c.name, i.id, i.amount, sum(p.amount) as payments 
     from clients c left join 
      invoices i 
      on c.id = i.client_id left join 
      payments p 
      on p.invoice_id = i.id 
     group by c.id, c.name, i.id, i.amount 
    ) ci 
group by name; 
+1

我不得不做一些调整,以适应我的表和顶部也选择'SUM(发票 - 付款)'和它的工作!看我的编辑。然而,重复的'id'('c.id'和'i.id')是冲突的,我重命名为'i.id AS invoiceid',并且它修复了它。 –