请考虑以下问题:
选择用户的所有payment
,并使用用户的UNION
invoice
结果。
SELECT `id`,
`amount` AS `value`,
'PAYMENT' AS `transaction_type`
FROM `payment`
WHERE `user_id` = $user_id
UNION ALL
SELECT `i`.`id`,
(-1) * SUM(`ii`.`unit_price` * `ii`.`quantity`) AS `value`,
'INVOICE' AS `transaction_type`
FROM `invoice` `i`
JOIN `invoiceitem` `ii` ON `ii`.`invoice_id` = `i`.`id`
WHERE `user_id` = $user_id AND `type` = 'invoice'
问题是对于没有付款且没有发票的用户,会返回不需要的行,如下所示:
id | value | transaction_type
=================================
NULL | 0 | NULL
但是对于拥有一些数据的用户,结果是完全可以预期的。
经过一些更多的研究,我得知问题应该来自下面的第二个子查询:
SELECT i.id,
(-1) * SUM(ii.unit_price * ii.quantity) AS `value`,
'INVOICE' AS `trans_type`
FROM invoice i
JOIN invoiceitem ii ON ii.invoice_id = i.id
WHERE user_id = 4 AND type = 'invoice'
返回以下内容:
id | value | transaction_type
=================================
NULL | NULL | INVOICE
当然,user_id = 4
的用户还没有任何发票。但对于另一个有发票的用户,结果还可以。
答案 0 :(得分:3)
此行由聚合函数SUM
创建。为了防止这种情况,请使用有效的GROUP BY
子句,可能是GROUP BY user_id
答案 1 :(得分:1)
要避免此类空值,只需使用LEFT JOIN
而不是INNER JOIN
,因此,请替换以下的sql行:
JOIN `invoiceitem` `ii` ON `ii`.`invoice_id` = `i`.`id`
这个:
LEFT OUTER JOIN `invoiceitem` `ii` ON `ii`.`invoice_id` = `i`.`id`
答案 2 :(得分:1)
如果不理解完整的表格描述,就不可能毫无疑问地说,但根据对问题的更新,您需要消除列i.id
具有NULL值的行:
SELECT i.id
, (-1) * SUM(ii.unit_price * ii.quantity) AS `value`
, 'INVOICE' AS `trans_type`
FROM invoice i
JOIN invoiceitem ii
ON ii.invoice_id = i.id
WHERE user_id = 4
AND type = 'invoice'
AND i.id IS NOT NULL
我猜你的数据模型中存在逻辑缺陷,或者你应该使用其他一些列。我可以推测这个invoice
行可能是一个已取消的订单,但显然存在id
列为空的行,这就是它出现在结果中的原因。