1

我有 3 张桌子

发票:身份证,客户

服务:invioce_id,价格

付款:invoice_id,金额

我想为每张发票选择所有服务价格为 amountDue 和任何付款金额为 amountPaid 的发票。

因此,例如,如果我有以下行:

发票

id = 1, client = 232
id = 2, client = 535

服务

invoice_id = 1, price = 5.00
invoice_id = 1, price = 10.00
invoice_id = 2, price = 20.00

付款

invoice_id = 1, amount = 7.00
invoice_id = 2, amount = 12.00
invoice_id = 2, amount = 8.00

我希望所有发票行的结果查询类似于:

发票

id = 1, client = 232, amountDue = 15.00, amountPaid = 7.00
id = 2, client = 535, amountDue = 20.00, amountPaid = 20.00

我有一个这样的查询:

SELECT invoices.*, 
sum(services.price) AS amountDue, 
sum(payments.amount) AS amountPaid 
FROM invoices 
LEFT JOIN services ON services.invoice = invoices.id 
LEFT JOIN payments ON invoices.id = payments.invoice 
GROUP BY invoices.id

但是得到的金额被乘以每张发票的服务数量。

有没有办法通过一个查询来提取所有数据?

4

1 回答 1

1

您有两个子表,它们在各自的连接中返回了不同的行数。如果您在没有分组/求和的情况下运行查询,您最终会得到:

+------+-----------+-------+-----------+--------+
| id   | serviceid | price | paymentid | amount |
+------+-----------+-------+-----------+--------+
|    1 |         1 |  5.00 |         1 |   7.00 |
|    1 |         1 | 10.00 |         1 |   7.00 |
|    2 |         2 | 20.00 |         2 |  12.00 |
|    2 |         2 | 20.00 |         2 |   8.00 |
+------+-----------+-------+-----------+--------+

请注意发票 #1 的付款金额 $7 和发票 #2 的服务价格是如何重复的。MySQL 试图通过从具有较少行的表中复制值来填补查询结构产生的“漏洞”。

要使这种查询起作用,您需要使用相关子查询,以便每个子查询可以进行自己的求和,而不受其他表的行数限制:

select invoices.id,
   (select sum(price) from services where services.iid = invoices.id ) AS service_price,
   (select sum(amount) from payments where payments.iid = invoices.id) AS payment_amount
FROM invoices;

产生

+------+---------------+----------------+
| id   | service_price | payment_amount |
+------+---------------+----------------+
|    1 |         15.00 |           7.00 |
|    2 |         20.00 |          20.00 |
+------+---------------+----------------+
于 2013-02-16T23:47:42.087 回答