0

私は2つのテーブルを持っています。offersoffer_status。行が欠落しているか、そのテーブルの列が 0offersの行を返したい。offer_statusdisabled

これが私がそれをやろうとした方法です:

SELECT offers.id,network,campid,name,url FROM offers
LEFT JOIN offer_status ON offers.id = offer_status.sql_id
AND offer_status.user_id='3'
WHERE country='US'

AND offer_status.disabled != '1'

ORDER BY epc DESC LIMIT 7

ただし、行がoffer_status存在しない場合 (および JOIN が失敗する場合)、これは機能しません。offer_status.disabled が null であるため、私にはまだ機能するはずです。

これは機能します:

SELECT offers.id,network,campid,name,url FROM offers
LEFT JOIN offer_status ON offers.id = offer_status.sql_id
AND offer_status.user_id='3'
WHERE country='US'

AND (offer_status.disabled IS NULL OR offer_status.disabled=0)

ORDER BY epc DESC LIMIT 7

しかし、私にはこれはパフォーマンスの点で悪いように思え、当初の考えがうまくいかなかったことにまだ失望しています.

上記の OR ステートメントはこれを行う唯一の方法ですか? より良い方法はありますか?

4

3 に答える 3

2

SQLロジックは、状態がTRUE、FALSE、およびUNKNOWNのトライステートロジックです。WHERE句は、条件がTRUEと評価される行を選択します。

NULL値をNULL以外の値と比較すると、3番目の論理状態であるUNKNOWN(タイトルで主張されているようにFALSEではない)が得られます。これはTRUEと同じではないため、条件がUNKNOWNと評価される行は選択されません。

明示的なISNULLテストを使用して、ヌル性をチェックできます。

AND (offer_status.disabled != '1' OR offer_status.disabled IS NULL)

安全性、明快さ、正確さのために余分な括弧に注意してください。

これがパフォーマンスへの影響が大きすぎる場合は、offer_status.disabled列にNOT NULL制約を適用すると、ISNULLテストまたはOR条件をいじる必要がなくなります。一般に、NOTNULLになる可能性のあるすべての列はNOTNULLである必要があります。これにより、データベースの操作がはるかに簡単になります。


offer_status.disabledがNULLの場合、次のことに注意してください。

WHERE offer_status.disabled  = '1' -- evaluates to UNKNOWN and the row is not selected
WHERE offer_status.disabled != '1' -- evaluates to UNKNOWN and the row is not selected

これは、タイトルで主張されている「NULLとの比較はFALSEを返す」という誤った動作と、「NULLとの比較はUNKNOWNを返す」の実際の動作との違いです。

于 2012-12-26T07:21:00.423 に答える
1

( 、、、などNULLを使用して)別の値と比較すると、が得られます。そして、真でも偽でもありません。第二に、条項を満たすために、条件は真と評価されなければなりません。=<><>NULLNULLWHERE

したがって、2番目のクエリは実際には正しい方法です。

IF完全を期すために、やなどの関数を使用してクエリを書き直すことができます(ただしお勧めしません)IFNULL

WHERE IFNULL(offer_status.disabled, 0) = 0
于 2012-12-26T07:21:29.103 に答える
0

MySQLドキュメントからの引用:

一方または両方の引数がNULLの場合、NULLセーフ<=>等式比較演算子を除いて、比較の結果はNULLになります。NULL <=> NULLの場合、結果はtrueです。

そうだと思います、(disabled IS NULL OR disabled=0)必要です。

于 2012-12-26T07:21:36.553 に答える