21

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

このビット列がNULLTRUEであるかNOTTRUEであるすべての行を取得しようとしています。

このクエリは本来あるべきものを返しません:(0行を返します)

Select * 
from table 
where bit_column_value <> 1

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

Select * 
from table 
where bit_column_value IS NULL

さて、2番目のクエリを使用できれば幸いですが、私の問題は、別のテーブルに対する同様のクエリで、上記の逆が当てはまり、最初の方法は機能しますが、2番目の方法は機能しないということです。

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

説明をよろしくお願いします。

4

5 に答える 5

30

<>動作しない理由は、SQLがNULL不明として扱われるためです。つまり、SQLは何を意味するのかわからないため、値とasのNULL両方=を評価します(where句またはjoin条件ではfalseとして扱われます)。詳細については、次をお読みください。SQLサーバーでNULL=NULLがfalseと評価されるのはなぜですか<>NULLUNKNOWN

インデックスがある場合、ISNULL関数を使用すると、インデックスを使用できないことを意味するため、クエリでインデックスを使用できるようにするには、次を使用しORます。

SELECT * 
FROM TableName
WHERE
   bit_column_value IS NULL OR bit_column_value = 0
于 2013-02-05T06:37:53.700 に答える
10

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

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

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

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

于 2013-02-05T06:21:55.743 に答える
3

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

WHERE句の条件は、条件がTRUEのときに行を選択することに注意してください。ほとんどのバイナリ述語(条件)では、NULLをある値と比較すると、結果はNULLまたはUNKNOWN(TRUEではない)になります。したがって、たとえば、列の値がNULLの場合、column = 0NULLまたは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}述部はわずかに異なります。テストされた値がNULLの場合、ISNULLテストはTRUEを返します。それ以外の場合は、FALSEを返します(UNKNOWNを返すことはありません)。IS [NOT] {TRUE | FALSE|UNKNOWN}テストも同様です。値が指定されたタイプの場合はTRUEを返し、それ以外の場合はFALSEを返します(UNKNOWNではありません)。例えば:

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またはNOTTRUEのすべての行を取得しようとしています。

仕様から直接クエリを記述してみてください。

  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は希望する結果をもたらします。ただし、MSSQLServerがIS[NOT]{TRUE | FALSE|UNKNOWN}をサポートしているかどうかはわかりません。述語に関するMSDNから判断すると、IS [NOT] {TRUE | FALSE | UNKNOWN}述語はサポートされていません(ただし、マニュアルの正しい部分を見逃している可能性があります)。それが正しければ、クエリ2または3のいずれかを使用する必要があります。


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

于 2013-02-05T07:27:46.557 に答える
1

値=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

于 2013-02-05T06:29:47.740 に答える
1

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

Select * 
from table 
where bit_column_value <> 1;

結果は出ません。NULL不明なので。この:

Select * 
from table 
where bit_column_value IS NULL;

あなたが探している結果をあなたに与えるでしょう。

しかし、データ型を使用してtruefalseを表すという誤解があります。bit

あなたはfalseをとして表しNULL0は空であり、trueはその他の値です。bitデータ型は、@ IswantoSanが彼の回答で説明したように機能します。0または1またはNULL

  • 0は偽、
  • 1は本当です、
  • NULL空です。

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

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

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

于 2013-02-05T06:38:07.693 に答える