我有一张invoices
桌子。每张发票都有许多invoice_items
和transactions
(或者,如果您愿意,“付款”)。对于每张发票,我想计算已付金额(即其交易金额的总和)和总金额(即项目金额的总和)。
我写了以下查询:
SELECT
invoices.*,
SUM(transactions.amount_cents) AS amount_paid,
SUM(invoice_items.quantity * invoice_items.price_cents) AS total
FROM invoices
RIGHT JOIN transactions
ON invoices.id = transactions.invoice_id
RIGHT JOIN invoice_items
ON invoices.id = invoice_items.invoice_id
但是,total
出于某种原因,该字段的值乘以交易次数(例如,如果我有一张总金额为20的发票和2笔交易,则该total
字段为40)。
如果我从查询中删除对事务的所有引用:
SELECT
invoices.*,
SUM(invoice_items.quantity * invoice_items.price_cents) AS total
FROM invoices
RIGHT JOIN invoice_items
ON invoices.id = invoice_items.invoice_id
该total
字段正确返回...
我不是这方面的专家,所以我可能正在做一些非常愚蠢的事情。我已经尝试过不同的 JOIN 组合,但没有结果。
有什么提示吗?
编辑:半最终解决方案
我试图得到未付的发票,所以这是最后的查询:
SELECT
invoices.*,
SUM(invoice_items.quantity * invoice_items.price_cents) AS total,
t.amount_paid
FROM invoices
LEFT JOIN invoice_items
ON invoice_items.invoice_id = invoices.id
LEFT JOIN (
SELECT
invoice_id,
SUM(transactions.amount_cents) AS amount_paid
FROM transactions
GROUP BY invoice_id
) t
ON invoices.id = t.invoice_id
GROUP BY invoices.id
HAVING amount_paid >= total;
编辑:意识到我不需要加入之后...
我真的不需要获取相关数据。我只想知道发票是已付还是未付。所以我最终使用了一个简单的 where:
SELECT `invoices`.*
FROM `invoices`
WHERE (
(
SELECT COALESCE(SUM(t.amount_cents), 0)
FROM transactions t
WHERE t.invoice_id = invoices.id
)
>=
(
SELECT COALESCE(SUM(i.quantity * i.price_cents), 0)
FROM invoice_items i
WHERE i.invoice_id = invoices.id
)
)
但是感谢所有帮助过的人。