Использование GROUP BY и HAVING для таблицы LEFT JOIN, где нет сохраненных записей - PullRequest
0 голосов
/ 01 апреля 2020

Есть таблица, в которой записываются данные оплаты по счетам. Я использую SUM для подсчета общей суммы платежа по счету. Я только хочу показать счета, которые не были оплачены. Поэтому я создал предложение WHERE, используя GROUP BY и HAVING, чтобы показывать только те записи, у которых сумма записей меньше общей суммы счета-фактуры.

Но ... Если в таблице платежей нет записей, которые можно найти , система не может найти счета для отображения. У кого-нибудь еще была эта проблема? Я открыт для перехода на другой формат, но мне нужно, чтобы он функционировал таким же образом, когда он находит только счета с суммами платежей меньше общей суммы счета, подлежащей оплате ИЛИ вообще никаких платежей.

$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
");

1 Ответ

1 голос
/ 01 апреля 2020

Ваша проблема в том, что когда не было произведено никаких платежей, SUM(p.payment_amount) равно 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
");
...