web-dev-qa-db-ja.com

SQL Serverでの比較中にnullを含めるにはどうすればよいですか?

したがって、基本的にSQL ServerではNULLは値がないため、比較できないため、予期しない結果が返されます。

たとえば、次のクエリでは、値IS NULLの行は返されませんが、次のようにします。

SELECT *
FROM table
WHERE
  (value != 26)
  AND date IS NULL
  AND last_modified >= '5/21/2014'

回避策として次のことができることを理解していますが、真剣にですか?括弧を追加し、フィールドを含めるたびに、すべてのフィールドでnullかどうかを確認する必要がありますか?醜く、直感的でクレイジーではないようです。

SELECT *
FROM table
WHERE
  (value != 26 OR value is null)
  AND date IS NULL
  AND last_modified >= '5/21/2014'

つまり、NULLは値ではないので比較できないことを知っていますが、実際には26でないことを推測できませんか? 26が何かで、NULLが何もない、何も何かではない場合、NULLは26ではありません。私にとっては論理的に思えます。

比較を使用するときに、毎回明示的なチェックを含める必要なしに、結果にnullをきれいに含める方法を誰かが知っていますか?また、テーブルでnullをオフにすることは、間違いなく選択肢ではありません。

編集:

私が示した方法でそれをしたくない理由の私の本当の問題は明らかにされませんでした。だからここに行く。私は、データベーステーブルへのクエリを作成して、ユーザーが動的にフィルターなどを作成できるようにするプログラムを書いています。このフィルターは、基本的に1日の終わりにSQLステートメントを作成し、ユーザーに表示する結果を取得します。ユーザーが選択したフィールドは、特定のデータベース内の任意のフィールドまたはすべてのフィールド、あるいはその両方にすることができます。ISNULLチェックを文字通りすべてのフィールドに適用しなければならない場合は、非常に非効率で、SQLを非常に見苦しくします。私のプログラムはテーブル定義にとらわれず、テーブルの内容を気にせず、テーブルの定義を知りたくありません。テーブルを選択し、等しい、等しくない、入力する、入力しないなどでフィルターするいくつかのフィールドを選択し、ボタンをクリックしてそのリクエストの結果を表示するだけです。

8
Brian T Hannan

はじめに、NULLは「値がない」という意味ではなく、SQL Serverでは「不明な値」という意味です。 ANSI_NULLSと呼ばれるセッション設定があり、クエリを希望どおりに動作させることができますが、非推奨であり、将来のバージョンでは強制的にON(好きではないようです)に強制されます: http ://msdn.Microsoft.com/en-us/library/ms188048.aspx

私はあなたがやろうとしていることを理解しています。そして、反論するために、レポートサービスやCognosのようなものによって生成されたクエリを見たことがあるかどうか尋ねます。もしそうなら、あなたが説明したいことを、あなたがしたくないことを正確に見るでしょう。どうして?まあ、nullを許可するスキーマがあれば、それがその方法です。それがすごく素晴らしくて素晴らしいアイデアだと言っているわけではありませんが、それはいつもうまくいきます。

設計者ができることは、その列がnullである可能性があるかどうかを確認することです。もしそうであれば、適切なロジックがそれをステップ実行して正しいクエリを作成できます。 「この列はnullの可能性があります。これらの値が必要ですか?」などのオプションを使用することもできます。エンドゲーム自体はわかりません。独自の動的クエリツールを作成することは、論理的な一貫性がすべて考慮される場合(このような場合)に非常に重要です。

Nullである可能性のある列に対して明示的なnullチェックを続けますが、それが最適に見えないことを確認しますが、常に機能します。

ANSI_NULL設定オプションは今のところ機能しますが、環境を制御していない場合は特にお勧めできません。さらに、後で強制的にONに設定され、とにかくアプリケーションロジックを書き直す必要があるエラーが発生します。これは、SQL ServerがNULLを処理する方法です。

9
Sean Gallardy

NULL問題はSQLの厄介な問題です。これは基本的に、現在地球上のすべてのSQLソフトウェアに焼き付いている間違いです。私たちはそれに対処しなければなりません。

_value <> 26 or value is null_は、このロジックを実装する良い方法です。同じセマンティクスの他の定式化があります。

値が_-1_でないことがわかっている場合(たとえば)、ISNULL(value, -1) <> 26と言うことができます。読みやすさの観点からは、これで良いとは思いません。この述部はSARG可能でない可能性があるため、オプティマイザーの問題を引き起こす可能性もあります。 _value is null_is一般的な考えに反して、SARG可能でインデックス可能な述語。

SQLには_IS DINSTINCT FROM_演算子がありますが、T-SQLではサポートされていません。 それを実装するためのリクエストに投票するために少し時間をかけてください! これは純粋に構文上の問題です。オプティマイザを変更する必要はまったくありません。その演算子は既に内部的にサポートされています。

TL; DR:今のやり方は正しいです。一緒に暮らしてください。

7
usr