0

请考虑以下查询:

选择payment一个用户的所有 s 和UNION该用户的invoices 的结果。

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还没有任何发票。但是对于另一个有一些发票的用户,结果是可以的。

4

3 回答 3

3

此行由聚合函数创建SUM。为了防止这种情况,请使用有效的GROUP BY子句,可能GROUP BY user_id

于 2013-06-22T20:57:21.340 回答
1

为避免此类空值,只需使用 aLEFT JOIN而不是INNER JOIN,因此,替换以下 sql 行:

JOIN `invoiceitem` `ii` ON `ii`.`invoice_id` = `i`.`id`

对于这个:

LEFT OUTER JOIN `invoiceitem` `ii` ON `ii`.`invoice_id` = `i`.`id`
于 2013-06-22T20:57:07.740 回答
1

如果不了解完整的表描述,就不可能肯定地说,但是根据对您问题的更新,您需要消除该列具有 NULL 值的行i.id

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列为空的行,这就是它出现在结果中的原因。

于 2013-06-23T13:43:50.050 回答