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
の値に違いがあったと思います。
説明をお願いします。
理由 <>
が機能しないのは、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
あなたの最善の策は、そのようなクエリを書くことです:
SELECT
*
FROM
table
WHERE
ISNULL(bit_column_value, 0) = 0
これにより、すべてのNULLおよびFALSEレコードが返されます。
テーブルの構造とデータを確認せずに、なぜ2つのクエリから異なる結果が得られるのかについてはコメントできません。
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であるすべての行を取得しようとしています。
指定から直接クエリを作成してみてください。
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value IS NOT TRUE
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value = FALSE
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value <> TRUE
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はそれらをサポートしていないようですので、二重にそうではありません。)
これは、すべてのデータがこの列にNULL
値を持っているためだと思います。そう:
Select *
from table
where bit_column_value <> 1;
結果は出ません。 NULL
は不明であるため。この:
Select *
from table
where bit_column_value IS NULL;
あなたが探している結果が得られます。
しかし、bit
データを使用してtrueおよびfalseを表すという誤解がありますタイプ。
falseをNULL
として表し、0
は空で、trueはその他の値です。 bit
データ型は @ IswantoSanが彼の回答で説明した ;として機能します。 0または1またはNULL
である必要があります。
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
の値とはまったく異なります。
値= 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