web-dev-qa-db-ja.com

IS NULL対<> 1 SQLビット

SQL Server 2012データベースのテーブルにビット列があります。

このビット列がNULLまたはNOT TRUEであるすべての行を取得しようとしています。

このクエリは、本来必要なものを返さない:(0行を返す)

Select * 
from table 
where bit_column_value <> 1

このクエリは正しい行を返します:

Select * 
from table 
where bit_column_value IS NULL

今、私は2番目のクエリを使用して幸せですが、私の問題は、別のテーブルの同様のクエリで、上記の逆が真であり、最初の方法は機能するが、2番目の方法は機能しないことです!

誰かが上記の違いを説明するのを手伝ってくれませんか?特に関連するビット列をNULLに更新しましたが、結果は変わりません。 (おそらく「空」とNullの値に違いがあったと思います。

説明をお願いします。

19
ché

理由 <>が機能しないのは、SQLがNULLを不明として扱うということです。SQLはNULLの意味がわからないため、両方を評価します=および<>NULL値に対してUNKNOWNとして(これは、where句または結合条件でfalseとして扱われます)。詳細については、次をお読みください: SQLサーバーでNULL = NULLがfalseと評価される理由

インデックスがある場合、ISNULL関数を使用すると、そのインデックスは使用できなくなります。クエリがインデックスを使用できるようにするには、ORを使用します。

SELECT * 
FROM TableName
WHERE
   bit_column_value IS NULL OR bit_column_value = 0
27
Bennor McCarthy

あなたの最善の策は、そのようなクエリを書くことです:

SELECT
     * 
FROM 
     table 
WHERE 
     ISNULL(bit_column_value, 0) = 0

これにより、すべてのNULLおよびFALSEレコードが返されます。

テーブルの構造とデータを確認せずに、なぜ2つのクエリから異なる結果が得られるのかについてはコメントできません。

7
SQLGuru

MSDNは [〜#〜] bit [〜#〜] タイプは値0、1、またはNULLを格納できると述べています。 (BIT値がNULLであるという事実は、8つのBIT値がバイトに格納されるようにビット値を圧縮できるため、ビット値自体とは別に格納する必要があります。)

WHERE句の条件は、条件がTRUEの場合に行を選択することに注意してください。ほとんどのバイナリ述語(条件)では、NULLをある値と比較すると、結果はNULLまたはUNKNOWN(TRUEではない)になります。したがって、たとえば、列の値がNULLの場合、column = 0はNULLまたはUNKNOWNに評価され、そのためcolumn <> 0

クエリを見る:

SELECT * FROM table WHERE bit_column_value <> 1

bit_column_value列が1の場合、条件はFALSEであるため、行は返されません。値が0の場合、条件はTRUEなので、行が返されます。値がNULLの場合、条件もNULLまたはUNKNOWNになるため、行は返されません。

SELECT * FROM table WHERE bit_column_value IS NULL

SQL標準によると、IS [NOT] NULL述語、および関連するIS [NOT] {TRUE | FALSE | UNKNOWN}述語は、わずかにIS NULLテストは、テストされた値がNULLの場合はTRUEを返し、それ以外の場合はFALSEを返します(UNKNOWNを返しません)。IS [NOT] {TRUE | FALSE | UNKNOWN}テストも同様です。値が指定されたタイプの場合はTRUEを返し、それ以外の場合は(UNKNOWNではなく)FALSEを返します。次に例を示します。

Column   IS TRUE   IS FALSE   IS UNKNOWN   IS NOT TRUE   IS NOT FALSE   IS NOT UNKNOWN
FALSE    FALSE     TRUE       FALSE        TRUE          FALSE          TRUE
TRUE     TRUE      FALSE      FALSE        FALSE         TRUE           TRUE
NULL     FALSE     FALSE      TRUE         TRUE          TRUE           FALSE

したがって、2番目のクエリでは、bit_column_value値はNULL(0と1の両方とは異なります)が選択されます。TRUEでもFALSEでもありません。


このビット列がNULLまたはNOT TRUEであるすべての行を取得しようとしています。

指定から直接クエリを作成してみてください。

  1. SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value IS NOT TRUE
  2. SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value = FALSE
  3. SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value <> TRUE
  4. SELECT * FROM table WHERE bit_column_value IS NOT TRUE

上記の真理値表を考えると、クエリ4は必要な結果を生成します。ただし、MS SQL ServerがIS [NOT] {TRUE | FALSE | UNKNOWNをサポートしていることは確かではありません。 Predicates に関するMSDNから判断すると、IS [NOT] {TRUE | FALSE | UNKNOWN}述語はサポートされていません(ただし、マニュアル)。それが正しい場合は、クエリ2または3のいずれかを使用する必要があります。


(値が単純な列ではなく行の値である場合、これらの述語にはいくつかの複雑な問題があります。しかし、それはあなたの質問や問題には関係ありません。MSSQL Serverはそれらをサポートしていないようですので、二重にそうではありません。)

2

これは、すべてのデータがこの列にNULL値を持っているためだと思います。そう:

Select * 
from table 
where bit_column_value <> 1;

結果は出ません。 NULLは不明であるため。この:

Select * 
from table 
where bit_column_value IS NULL;

あなたが探している結果が得られます。

しかし、bitデータを使用してtrueおよびfalseを表すという誤解がありますタイプ。

falseNULLとして表し、0は空で、trueはその他の値です。 bitデータ型は @ IswantoSanが彼の回答で説明した ;として機能します。 0または1またはNULLである必要があります。

  • 0はfalse、
  • 1はtrue、
  • NULLが空です。

したがって、取得するには:

  • trueの値にはwhere bit_column_value = 1を使用します。
  • falseの値にはwhere bit_column_value = 0を使用します。
  • NULLまたは空のwhere bit_column_value IS NULL
  • NULL or not true:where bit_column_value IS NULLまたはbit_column_value = 0`。

注意すべきもう1つの点は、NULLとemptyは2つの異なるものであり、同じではないということです。 BITデータ型の場合、空はNULLが0ではなく、0がfalseであると想定されているためです。ただし、たとえば、VARCHARのような文字列データ型を検討してください。空の文字列''は、NULLの値とはまったく異なります。

1
Mahmoud Gamal

値= 0が含まれている場合は、テーブルデータを確認してください。

SQLビットデータ型 は0、1、またはNULLのいずれかの値のみを持つことができ、他の値を挿入した場合、1と見なされます(例外: 'Falseを挿入した場合'0になります、' True 'は1)になります。

例えば ​​:

insert into t1 values (1),(2),(1),(3),(-1),(0),(NULL),('false'),('true')

結果 :

1、1、1、1、1、0、NULL、0、1

1
Iswanto San