2012-04-07 7 views
1

こんにちは専門家をフィルタリングし挙動はNULL値に

enter image description here

私は何のメッセージを参照してくださいどのようなユーザーを決定するために、別のテーブルを持っている:

enter image description here

今、私は、メッセージdidinotの期限が切れた場合、ユーザーが見ていないというメッセージを表示するようにクエリを記述します。(例えば、それはそうでBeginYearとEndYear間の年だと...)。

SELECT * 
FROM 
tblAlarms LEFT OUTER JOIN tblUsersAlarms tua ON tblAlarms.Id=tua.MessageID 
WHERE @CurrentYear BETWEEN tblAlarms.BeginYear AND tblAlarms.EndYear 
    AND @CurrentMonth BETWEEN tblAlarms.BeginMonth AND tblAlarms.EndMonth 
    AND @CurrentDay BETWEEN tblAlarms.BeginDay AND tblAlarms.EndDay 
    AND @CurrentHour * 60 + @CurrentMinute BETWEEN tblAlarms.BeginHour*60 + tblAlarms.BeginMinute AND tblAlarms.EndHour*60 + tblAlarms.EndMinute 
    --AND (tua.UserID <> 128 AND tua.UserID IS NULL) 

、それが返されます:私はこのクエリを記述

enter image description here

が、私のコメントを解除した場合、最後の行には、私は、ユーザーが見ていないことをどのようなメッセージを決定することができます任意のrecord.Howを返しません。 ?

ありがとう

答えて

6

NULLと値を比較した結果はUNKNOWNです。フィルタ条件は、条件がTRUEと評価される行のみを選択するため、条件がFALSEまたはUNKNOWNと評価される行は選択されません。

IS NULLIS NOT NULLのテストは異なるため、常にTRUEまたはFALSEの回答が得られます。また、column = NULLまたは​​と書くこともできません(少なくとも、SQL標準では許可されていないため、一部のSQL方言は可能です)。

あなたの条件は次のとおりです。tua.UserIDの値がNULLの場合

AND (tua.UserID <> 128 AND tua.UserID IS NULL) 
  • は、その後、第2項はTRUEと評価されますが、最初の意志はその後、UNKNOWN、およびUNKNOWNに評価し、TRUEがUNKNOWNです、これはTRUEではないため、行は選択されません。

  • tua.UserIDの値がNULLでない場合、2番目の項はFALSEと評価されるため、全体的な条件はFALSEと評価され、行は選択されません。

したがって、条件を追加すると、観察したとおりに何も選択されません。

より典型的には、あなたの状態は、これら二つのどちらかになります:

AND (tua.UserID <> 128 AND tua.UserID IS NOT NULL) 

AND (tua.UserID <> 128 OR tua.UserID IS NULL) 

最初の選択肢では、二重の条件が実際には冗長です。 tua.UserIDがNULLの場合、最初の項はUNKNOWNと評価されるため、全体的な条件はTRUEでなくなり、行は選択されません。 2番目の選択肢は非常に便利です。

+0

ありがとうございますが、最後の2つの条件が私の条件を満たすものではありません – Arian

+3

あなたの質問には答えがわかりません。私はあなたが何をしたいか明確ではありません。私はあなたに今日の魚を与えないで魚の習慣を学ぶのを手伝っています。 –

0

NULL」は、「値がわからない」という意味です。それは「価値がない」という意味ではありません。したがって、引数の1つとしてNULL値を使用して比較を実行すると、実際の(しかし不明な)値に応じて、結果はTRUEまたはFALSEになります。ただし、UNKNOWNは有効な比較結果ではないため、この場合の出力はFALSEです。あなたは二つの値(フィールドまたはリテラル)の間=!=<<=>>=<>のような比較です-オペレータを入れており、この値のいずれかがNULLで、その比較 - 演算の結果が

は常にFALSEです。

すでに使用されているNULL値のための2つの特別な比較演算子があります:IS NULLIS NOT NULLです。どちらもバイナリ演算子ではなく、単項演算子です。つまり、彼らには2つの議論がありませんが、1つしかありません。それらの引数がNULL値かどうかをテストします。

tua.UserIDNULLの場合、tua.UserID <> 128FALSEである必要があります。他の部分tua.UserID IS NULLTRUEですが、FALSE AND TRUEFALSEです。これにより、すべての行に対して完全なWHERE-Condition FALSEが作成されます。

+0

-1ヌルは値ではなく、「欠落している値のマーカー」SQLはなぜ値が不足しているのか分からない - セマンティクスは[アプリケーション設計者の仕事]です。必要に応じて「任意の値にする」。 SQLでは 'UNKNOWN'は確かに比較の有効な結果です。あなたがnullを含むリストに載っている演算子を使った比較は、必ずしもFALSEを評価するとは限りません。 – onedaywhen