0

次のクエリを検討してください。

ユーザーのすべて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

しかし、ある程度のデータを持っているユーザーにとっては、結果は完全に予期されたものです。


重要な編集

さらに調査した結果、問題は以下の2番目のサブクエリにあるはずであることがわかりました。

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はまだ請求書がありません。しかし、いくつかの請求書を持っている別のユーザーの場合、結果は OK です。

4

3 に答える 3

3

この行は、集計関数によって作成されますSUM。これを防ぐには、有効なGROUP BY節を使用してください。GROUP BY user_id

于 2013-06-22T20:57:21.340 に答える
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

データモデルに論理的な欠陥があるか、使用する必要がある他の列があると推測しています。この行はキャンセルされた注文である可能性があると推測できますが、列が null でinvoiceある行が存在することは明らかです。これが結果に表示される理由です。id

于 2013-06-23T13:43:50.050 に答える
1

このような null を回避するには、 のLEFT JOIN代わりにa を使用するだけな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 に答える