web-dev-qa-db-ja.com

SQL Serverは、<>と等しくない行とNULLを返します

RowTypeID =(1,2,3、またはnull)の値の列を持つテーブルがあります。 3の値を持たない行を返すクエリを記述したいと思います。この例では、すべてのNULL行とすべての1,2行が必要ですが、値が3の行は必要ありません。

Set ANSI null ONが現在データベースに設定されています。

なぜ書けないのか知りたい

select * from myTable where myCol <> 3

このクエリは、myCol列にNULLがある行を返しません。

私は書く必要があります

select * from my Table where myCol <> 3 or myCol Is NULL 

IS NULLを常に含める必要がありますか、それとも、where句myCol <> 3が私のColの値としてNullを持つ行を返すように設定できますか?

19
pehaada

私はあなたのアプローチは素晴らしいと思います:

SELECT *
FROM MyTable
WHERE myCol <> 3 OR myCol IS NULL

代替を求めているので、もう1つの方法は、列をNOT NULLにして、NULLの代わりに別の(そうでなければ未使用の)値をデータベースに格納することです(例:-1)。次に、式myCol <> 3は、他の値と同じようにfake -NULLに一致します。

SELECT *
FROM MyTable
WHERE myCol <> 3

ただし、一般的にはこのアプローチを使用することをお勧めします。あなたがすでにそれをしている方法は正しい方法です。

また、他のいくつかのデータベースがIS DISTINCT FROMをサポートしていることにも言及する価値があるかもしれません。

SELECT *
FROM MyTable
WHERE myCol IS DISTINCT FROM 3

MySQLには NULL-safe equal があり、この目的にも使用できます。

SELECT *
FROM MyTable
WHERE NOT myCol <=> 3

残念ながら、SQL Serverはこれらの構文のいずれもまだサポートしていません。

16
Mark Byers

NULL評価は不明 を含む式であるため、NULLは何らかの方法で処理する必要があります。必要に応じて、代わりに次のようにすることができます。

select *
from MyTable
where isnull(MyColumn, -1) <> 3

ただし、これにはマジックナンバー(-1)が含まれ、IS NULLの元のテストよりもおそらく読みにくくなります。

Edit:そして、SQLMenaceが指摘するように、 SARGable ではありません。

3
RedFilter

値をテストするときは常に、すべてのNULLが省略されます。結局のところ、一部の列の値が特定の基準を満たし、NULLがnot a valueであるかどうかをテストしています。

2
Joey

IS NULLを常に含める必要がありますか、それとも、colの値としてNullを持つ行をwhere句myCol <> 3が返すように設定できますか?

あなたalwaysalways、常にis nullを含める必要があります。

3はNot/Applicableと等しくなく、Unkownと等しくないためです。

1
nate c

nULLを他のものと比較することはできないため、NULLはNULLにさえ等しくありません

DECLARE @i INT
DECLARE @i2 INT

SELECT @i = NULL, @i2 = NULL

IF @i = @i2
PRINT 'equal'
ELSE 
PRINT 'not equal'
0
SQLMenace