我有一个带有四个IF语句的MySQL查询,应该根据里面的条件将别名设置为“1”或“0”。虽然我没有任何错误,但唯一返回正确值的IF是具有is_paid
别名的IF。
我仔细检查了其他三个别名的条件,即使它们没问题,我仍然会得到虚假的结果。
我做错了吗?有什么办法可以编写查询,这样我就能得到预期的结果吗?
以下是查询:
SELECT r.doc_number,
r.doc_date,
r.due_date,
r.currency,
r.amount,
r.vat,
r.vatammount,
(r.amount + r.vatammount) final_amount,
r.currency,
b.boq_id,
b.boq_comp_id,
b.boq_client_id,
b.boq_agency,
b.boq_date,
b.boq_orders,
b.receivable_id,
c.comp_name,
crm.`cn-name-first`,
crm.`cn-name-last`,
bi.inv_path,
(SELECT SUM(amount_recieved) FROM receivables_payments WHERE r_id = b.receivable_id) total_amount_received,
IF (r.amount + r.vatammount = (SELECT SUM(amount_recieved) FROM receivables_payments WHERE r_id = b.receivable_id), '1', '0') AS is_paid,
IF (CURRENT_DATE >= r.due_date AND r.amount + r.vatammount != (SELECT SUM(amount_recieved) FROM receivables_payments WHERE r_id = b.receivable_id), '1', '0') AS is_overdue,
IF (r.due_date < CURRENT_DATE AND r.amount + r.vatammount != (SELECT SUM(amount_recieved) FROM receivables_payments WHERE r_id = b.receivable_id), '1', '0') AS is_outstanding,
IF (r.due_date = CURRENT_DATE AND r.amount + r.vatammount != (SELECT SUM(amount_recieved) FROM receivables_payments WHERE r_id = b.receivable_id), '1', '0') AS is_due_today
FROM receivables r
LEFT JOIN boq b ON b.receivable_id = r.id
LEFT JOIN boq_invoices bi ON bi.inv_boq_id = b.boq_id
LEFT JOIN comp_companies c ON c.comp_id = b.boq_comp_id
LEFT JOIN crm_contacts crm ON crm.contact_id = b.boq_client_id
WHERE r.status = 'active'
AND r.doc_type = 'inv'
AND b.boq_status = 'active'
GROUP BY r.id
HAVING is_due_today = '1'
ORDER BY r.doc_date DESC
LIMIT 10
答案 0 :(得分:0)
您遇到null
- 比较问题。 20 != 0
为true
,但20 != null
为null
(效果与false
中的IF
相同。)
IF (... r.amount + r.vatammount !=
(SELECT SUM(amount_recieved)
FROM receivables_payments WHERE r_id = b.receivable_id)
, '1', '0') AS is_overdue,
如果null/false
中没有任何符合行的情况,将为receivables_payments
(因此可能在没有任何付款的情况下),因为SUM(amount_recieved)
将是null
。所以你不会得到正确的旗帜。
当值为coalesce(value,0)
时,您可以使用0
获取null
,以便您可以按照以下方式进行比较:
IF (... r.amount + r.vatammount !=
COALESCE(SELECT SUM(amount_recieved)
FROM receivables_payments WHERE r_id = b.receivable_id),0)
, '1', '0') AS is_overdue,
实际上,对于使用总和的所有5列(标志和total_amount_received
),您应该执行此操作,例如,如果您的帐单金额为0
,则标记is_paid
也不正确。
答案 1 :(得分:0)
您的查询存在一般问题:
max(b.boq_id)
的应收款的所有Boq的最大boq_id)。所以你只需要显示一个匹配的boq_id,一个匹配的boq_comp_id等,都是任意选择的。它们甚至不必属于同一条记录,因此您可以从一条记录中获取boq_id,从另一条记录中获取boq_comp_id等。b.boq_status = 'active'
。外连接记录的列为NULL。因此,没有外部联接记录匹配,因此您立即解雇它们。你想要到外连接,然后把条件放在ON子句中,或者你没有,然后使用INNER JOIN(或简短的JOIN)。现在进行评估:
对我来说没问题。好吧,你将超额付款视为未支付,但也许你的数据库中不可能。如果未达到金额且今天为due_date,则设置is_overdue和is_due_today。如果未达到金额并且due_date是上周,则设置is_overdue和is_outstanding。
不是这样的吗?你和他们的实际问题是什么?