NULLと等しくない<>!=演算子


271

誰かがSQLの次の動作を説明できますか?

SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)

回答:


309

<>標準SQL-92です。!=同等です。どちらも値を評価しますが、そうでNULLはありません- 値がないことNULLを示すプレースホルダーです。

そのため、このような状況ではIS NULL/ IS NOT NULLを述語としてのみ使用できます。

この動作はSQL Serverに固有のものではありません。すべての標準準拠SQL方言は同じように機能します。

値がnullないかどうかを比較するにを使用しIS NOT NULLnullない値と比較するにを使用します<> 'YOUR_VALUE'。値がNULLと等しいか等しくないかはわかりませんが、値がNULLかNOT NULLかはわかりません。私の値がNULL以外の値かどうかを比較できます。


4
実は、私はそれがあると考えている<>ことが92スペックであるが、ほとんどのベンダーがサポート!=および/またはそれが99または03のような以降の仕様に含まれている
トーマス

2
@Thomas:!=私が理解しているように、Oracleは〜9i までサポートしませんでした。これにより、多くのANSI-92構文が導入されました。MySQLも同様で、4.xでサポートを開始すると私は信じています。
OMGポニー2011

これは!=、の代替として後の仕様に含まれている可能性があることを示唆しているようです<>。新しいスペックを手に入れてはいけないので、はっきりとは言えません。
トーマス

2
結果であるWHERE MyColumn != NULLWHERE MyColumn = NULL、確定?または言い換えるとMyColumn、データベースでnullが可能かどうかに関係なく、常に0行を返すことが保証されていますか?
スラウマ

11
また!=、値のみを評価するため、次のようなWHERE MyColumn != 'somevalue'ことを行ってもNULLレコードは返されないことにも注意してください。
jsumrall 2015

88

NULLには値がないため、スカラー値演算子を使用して比較することはできません。

つまり、NULLには値がないため、値をNULLに等しくする(または等しくない)ことはありません。

したがって、SQLには、特殊なIS NULLおよびNULLを処理するためのIS NOT NULL述部があります。


3
+1。また、OPステートメントとは異なり、これは「Microsoft SQL」ではありません。3値論理はSQL標準で定義されており、この点でMSは標準に準拠しています。
TomTom

6
これがマイクロソフトのみの動作であることを示唆していませんでした。私は単にMicrosoft SQL Serverでそれを観察したと述べていました。
Maxim Gershkovich、2011

13
興味深いことに、この(予想される)動作が役立つ状況はありますか?それはちょうどした私には思える'a' != null(値を返さないtrue/ 1カウンタ直感的であり、時間から時間に私をキャッチ)!私は「無価値と比較したある価値」は常に「等しくない」だろうと思っていましたが、多分それは私だけですか?!?
DarthPablo 2014年

1
私は人々がNULLを「価値がない表現しているのは興味深いと思います。同様に、数値1が実際に値であるときに「値がある」と言うのと同じです。しかし、NULLは非値を表して...
systemaddict

手動による回避策として、SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'センチネル値x(この場合は文字列/文字)に適切なデータ型を指定すると、NULL値の場合に定数を割り当てることができます。これはTSQL構文ですが、Oracleと他のエンジンには同様の機能があります。
systemaddict

26

この動作はデフォルト(ANSI)の動作であることに注意してください。

もし、あんたが:

 SET ANSI_NULLS OFF

http://msdn.microsoft.com/en-us/library/ms188048.aspx

異なる結果が得られます。

SET ANSI_NULLS OFF どうやら将来的にはなくなるでしょう...


8
+1 ...十分ではありません。インデックスで「重複した」NULLを取得できるのはいつですか?:(

フィルターされたインデックス(例create unique index UK_MyTable on MyTable (Column) where Column is not null)にWHERE句を追加することにより、SQL Serverインデックスで重複したNULLを取得できます:msdn.microsoft.com/en-us/library/cc280372.aspx
Anthony Mills

3
ドキュメントからの注意:場合はSET ANSI_NULLSOFFで、等号(=)とされないに等しい(<>)比較演算子は、ISO規格に従っていません。を使用するSELECTステートメントはWHERE column_name = NULL、column_nameにnull値を持つ行を返します。を使用するSELECTステートメントWHERE column_name <> NULLは、列にnull以外の値を持つ行を返します。また、を使用するSELECTステートメントWHERE column_name <> XYZ_valueは、XYZ_valueでなく、NULLでないすべての行を返します。私見、この最後のステートメントは、結果からのnullの除外で少し奇妙に見えます!
DarthPablo 2014年

4
msdnドキュメントからの重要な注意: SQL Serverの将来のバージョン[2014以降]では、ANSI_NULLSは常にオンになり、オプションを明示的にオフに設定したアプリケーションはエラーを生成します。新しい開発作業ではこの機能を使用せず、現在この機能を使用しているアプリケーションの変更を計画してください
Otiel

7

SQLでは、NULL結果を使用して評価または計算したものはすべてUNKNOWNになります。

このためSELECT * FROM MyTable WHERE MyColumn != NULLSELECT * FROM MyTable WHERE MyColumn <> NULL結果は0になります。

NULL値のチェックを提供するために、isNull関数が提供されています。

さらに、IS3番目のクエリで使用したように演算子を使用できます。

お役に立てれば。


「SQLでは、NULLで評価または計算した結果はすべて「NULL」になります」-不正解。あなたが意味する結果は不明です。
39:39

@MahendraLiya NULLをチェックするisNull関数は提供されていませんが、「指定された置換値でNULLを置き換えます。」ISNULLの代わりにIS NULLまたはIS NOT NULLを使用する必要があります。これは別の方法です。
2018


6

を使用しております

SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';

MyColumnがNULLであるすべての行、またはMyColumnが空の文字列であるすべての行を返す。多くの「エンドユーザー」にとって、NULLと空の文字列の問題は、必要がなく、混乱のない点で区別されます。


5

nullが他の値や他のnullに匹敵しないという機能的でシームレスな理由はわかりません。それを明確に比較して、コンテキスト内で同じであるかどうかを判断できるからです。それはおかしいです。論理的な結論と一貫性があるからといって、常にそれに悩まされる必要があります。それは機能的ではなく、より機能的にし、それが一貫性があるかどうか、そして「普遍的な論理」を保持しているかどうかを結論付けるのは哲学者や科学者に任せます。:)誰かがそれがインデックスか何かのためであると言うかもしれません、私はそれらが値と同じヌルをサポートするように作ることができなかったことを疑います。これは、2つの空のグラスを比較するのと同じです。1つはつるガラスで、もう1つはビールグラスです。オブジェクトのタイプではなく、オブジェクトに含まれる値を比較します。intとvarcharを比較するのと同じように、nullです。さらに簡単です。何もないことと、2つの何もない点に共通点があります。それらは同じであり、私とSQLを書く他のすべての人が明確に比較できます。私たちのためにそれを行うためにコンピューターの電源を使用しないのはなぜですか。関連するすべてがそれを念頭に置いて構築されている場合、物事が遅くなるとは思えません。「それはnullではない、それは何もない」、それはアップルではない、それはapfelだ、さあ…機能的にはあなたの友達であり、ここにもロジックがあります。最終的に重要なのは機能性だけであり、そのようにnullを使用することで、多かれ少なかれ機能性と使いやすさがもたらされます。もっと便利ですか?なぜなら、いくつかのANSI標準のために、それらを奇妙な方法で比較することによって、常にそのロジックを壊しているからです。私たちのためにそれを行うためにコンピューターの電源を使用しないのはなぜですか。関連するすべてがそれを念頭に置いて構築されている場合、物事が遅くなるとは思えません。「それはnullではない、それは何もない」、それはアップルではない、それはapfelだ、さあ…機能的にはあなたの友達であり、ここにもロジックがあります。最終的に重要なのは機能性だけであり、そのようにnullを使用することで、多かれ少なかれ機能性と使いやすさがもたらされます。もっと便利ですか?なぜなら、いくつかのANSI標準のために、それらを奇妙な方法で比較することによって、常にそのロジックを壊しているからです。私たちのためにそれを行うためにコンピューターの電源を使用しないのはなぜですか。関連するすべてがそれを念頭に置いて構築されている場合、物事が遅くなるとは思えません。「それはnullではない、それは何もない」、それはアップルではない、それはapfelだ、さあ…機能的にはあなたの友達であり、ここにもロジックがあります。最終的に重要なのは機能性だけであり、そのようにnullを使用することで、多かれ少なかれ機能性と使いやすさがもたらされます。もっと便利ですか?りんごじゃなくて、さあさあ…機能的にはあなたの友達であり、ここにもロジックがあります。最終的に重要なのは機能性だけであり、そのようにnullを使用することで、多かれ少なかれ機能性と使いやすさがもたらされます。もっと便利ですか?りんごじゃなくて、アフェルです...機能的にはあなたの友達であり、ここにもロジックがあります。最終的に重要なのは機能性だけであり、そのようにnullを使用することで、多かれ少なかれ機能性と使いやすさがもたらされます。もっと便利ですか?

このコードを考えてみましょう:

SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end

このコードが何を返すかを知っている人はどれくらいいますか?NOTの有無にかかわらず、0を返します。これは機能的ではなく、混乱を招きます。C#ではすべてがそうであるように、比較演算は値を返します。論理的にはこれも値を生成します。それがなかった場合、比較するものがないためです(例外:なし:))。彼らはただ「言った」:nullが0を返すものと比較すると何でも、それは多くの回避策と頭痛の種を生み出します。

これは私をここに連れてきたコードです:

where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)

2つのフィールド(の場所)の値が異なるかどうかを比較するだけで、関数を使用できますが...


4

NULL比較演算子を使用して値と比較することはできません。NULL = NULLはfalseです。Nullは値ではありません。IS演算子は、NULL比較を処理するように特別に設計されています。


5
アドホッククエリでnull = null使用する可能性のある場所を時々使用するとき、私は常に混乱した人々を楽しませてきました1=0。そして、彼らが不平を言ったら、私はそれをnull != null:) に変更します
SWeko

8
「NULL = NULLは偽です」そうではありません。NULL = NULLは、falseではなく、unknownと評価されます。
nvogel

@dportasはそうですが、条件付きでは真と評価されないことを意味しました。
Vincent Ramdhanie

@VincentRamdhanieどちらも偽として; 実際、postgresではNULLとして評価されます
Pere

2

古い質問ですが、以下はさらに詳細を提供するかもしれません。

null値がないか不明な値を表します。値がない理由が特定されていないため、あいまいさが生じる可能性があります。

次のようなクエリを実行するとします。

SELECT *
FROM orders
WHERE delivered=ordered;

つまり、ordereddelivered日付が同じである行を探しています。

1つまたは両方の列がnullの場合はどうなりますか?

少なくとも1つの日付が不明であるため、2つの日付が同じであるとは期待できません。これは、両方の日付が不明な場合に当てはまります。日付がわからない場合でも、日付を同じにするにはどうすればよいでしょうか。

このため、null値として扱う式はすべて失敗する必要があります。この場合、一致しません。これは、次のことを試みた場合にも当てはまります。

SELECT *
FROM orders
WHERE delivered<>ordered;

繰り返しになりますが、2つの値が何であるかわからない場合、2つの値は同じではないと言えるでしょうか。

SQLには、欠損値に対する特定のテストがあります。

IS NULL

具体的には、値を比較するのではなく、欠損値を探します。

最後に、!=オペレーターに関しては、私の知る限り、実際にはどの規格にも含まれていませんが、非常に広くサポートされています。これは、一部の言語のプログラマーがよりくつろげるようにするために追加されました。率直に言って、プログラマーが使用している言語を思い出せない場合、彼らは悪いスタートを切っています。


これは、@ Hoveが彼の回答で述べているのと同じ「無意味な」「論理」です。真実は、この文脈ではその余分な道具は必要ないということです。何かをNULLと比較する場合、値を「値を持っている」と比較しているNULLのではなく、「アンダーレイNULLが「持っている」未決定の値と比較しているのではなく、「明らかに、これまで知ることはできません。それは本当に物事を楽にするでしょう。
ペレ

@Pere私はそれが厳密に「無意味」だとは言いませんし、執筆IS NULLが執筆よりもはるかに困難であるかどうかはわかりません= NULL。後者を特別なケースとして扱うのではなくWHERE columnA = columnB、と同じ解釈を持っている場合、より一貫性があると思いますWHERE columnA = NULL。は値でNULLないことに注意してください。テストすること正当であるプログラミング言語では、別の意味variable == nullがあるためnullです。それは未知の何かを表すのではなく、値の意図的なリセットです。SQLではそうではありません。
Manngo

@Mangoo;)(および「ロジック」)を引用符で囲んでいるのはそのためです。私に怒らないでください。私はあなたの説明ではなく、ANSIの「推論」について話していました。あなたの最新の例ではIS NULLANDの間にオーバーヘッドがないことに同意し=NULLます。しかし、ホバーの最後のものを見てください。何度も何度も体験するのに疲れました。追加のチェック...
Pere

1

値に変更iがあり、新しい値でありd、古い値であるかどうかを確認するために作成したこのコードを提案したいと思います (順序は重要ではありません)。さらに言えば、値からnullへ、またはその逆への変更は変更ですが、nullからnullへの変更は変更されません(もちろん、値から別の値への変更は変更ですが、値から同じへの変更ではありません)。

CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
    @i sql_variant,
    @d sql_variant
)
RETURNS bit
AS
BEGIN
    DECLARE @in bit = 0, @dn bit = 0
    if @i is null set @in = 1
    if @d is null set @dn = 1

    if @in <> @dn
        return 0

    if @in = 1 and @dn = 1
        return 1

    if @in = 0 and @dn = 0 and @i = @d
        return 1

    return 0

END

この機能を使用するには、次のことができます

declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)

---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp

---- where equal ----
select *,'equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 1

---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 0

結果は次のとおりです。

---- in select ----
a   b   =
1   1   1
1   2   0
1   NULL    0
NULL    1   0
NULL    NULL    1

---- where equal ----
1   1   equal
NULL    NULL    equal

---- where not equal ----
1   2   not equal
1   NULL    not equal
NULL    1   not equal

sql_variantを使用すると、さまざまな型と互換性があります


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.