首页 > 解决方案 > 在没有存储记录的 LEFT JOIN 表上使用 GROUP BY 和 HAVING

问题描述

有一个表格记录了发票的付款数据。我正在使用 SUM 来计算发票的总付款金额。我只想显示尚未支付的发票。因此,我使用 GROUP BY 和 HAVING 创建了一个 WHERE 子句,仅显示记录总和小于发票总金额的记录。

但是...如果在“付款”表中没有要查找的记录,系统将找不到要显示的任何发票。其他人有这个问题吗?我愿意更改为不同的格式,但我需要它以相同的方式运行,即只查找付款金额小于应付发票总金额或根本没有付款的发票。

$query = "
SELECT o.id, o.user_id,o.invoice_number,o.total,SUM(p.payment_amount) as paid 
FROM User_Order_Details as o 
LEFT JOIN User_Payments as p ON (p.user_id = o.user_id AND p.order_id = o.id) 
WHERE o.user_id = '1' AND o.invoice_number != '' 
GROUP BY p.order_id 
HAVING SUM(p.payment_amount) < o.total 
ORDER BY o.ship_date DESC
");

标签: mysqlleft-joinhaving

解决方案


您的问题是,当没有付款时,SUM(p.payment_amount)is NULL,并且与NULL任何东西进行比较总是会导致FALSE(因此HAVING SUM(p.payment_amount) < o.total不会返回这些行)。因此,您需要使用COALESCE将该值转换为0,然后才能成功进行比较。请注意,MySQL 允许您在HAVING子句中使用别名,因此您可以在paid此处使用:

$query = "
SELECT o.id, o.user_id,o.invoice_number,o.total, COALESCE(SUM(p.payment_amount),0) as paid 
FROM User_Order_Details as o 
LEFT JOIN User_Payments as p ON (p.user_id = o.user_id AND p.order_id = o.id) 
WHERE o.user_id = '1' AND o.invoice_number != '' 
GROUP BY p.order_id 
HAVING paid < o.total 
ORDER BY o.ship_date DESC
");

推荐阅读