我有一个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;
编辑:实现后我不需要加入......
我真的不需要获取相关数据。我只是想知道发票是付还是不付。所以我最终使用了一个简单的地方:
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
)
)
但感谢所有帮助过的人。
答案 0 :(得分:2)
您可以使用子查询来聚合每个invoice_id最多一行的事务,这样就不会导致额外的行发生。根据卷的不同,您可能希望将子查询配置到临时表中并引用临时表。
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
答案 1 :(得分:2)
您的复制是基于笛卡尔结果...正如您所指出的,一张发票有多个交易,因此交易金额每次存在时都会计算在内。您可能需要来自各个表的子查询,以便按发票ID ...
分组SELECT
invoices.*,
Payments.Amount_Paid,
Items.Items_Total
FROM
invoices
JOIN ( select
T.Invoice_ID,
sum( T.amount_cents ) amount_paid
from
transactions T
group by
T.Invoice_ID ) Payments
on Invoices.id = Payments.Invoice_ID
JOIN ( select
II.Invoice_ID,
sum( II.quantity * II.price_cents) AS Items_total
from
Invoice_Items II
group by
II.Invoice_ID ) Items
on Invoices.id = Items.Invoice_ID