14

それで、今朝、私は正しく表現しなかった質問をしました、それで私は何よりもNULLがNULL/FALSEを与える理由について多くの回答を得ました。

私の実際の質問は、dbguysが両方ともNULLになる可能性のある2つの列の不等式をテストするという昔ながらのやり方は何であるかということでした。私の質問は、この質問の正反対です。

要件は次のとおりです。AとBは2つの列です。a
)AとBが両方ともNULLの場合、それらは等しく、FALSEを返します
。b)AとBが両方ともNULLでない場合、A <> Bを返します
。c)いずれかの場合AまたはBがNULL、等しくない、TRUEを返す

4

9 に答える 9

10

列のデータ型と可能な値に応じて、次のようになります。

COALESCE(A, -1) <> COALESCE(B, -1)

秘訣は、データに表示されない値(ここでは-1を使用)を見つけることです。

他の方法は次のようになります。

(A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL)

これは、特定のRDBMSがNULLを処理する方法によっては問題になる可能性があります。ANSI規格では、これにより必要なものが得られるはずですが、とにかく誰が規格に準拠しています。:)

PS-COALESCE関数を使用すると、列を比較する際のインデックスの使用が無効になる可能性があることも指摘しておく必要があります。クエリプランとクエリのパフォーマンスをチェックして、それが問題であるかどうかを確認します。

PPS-OMGPoniesがInformixがCOALESCEをサポートしていないと述べていることに気づきました。これは私が信じているANSI標準関数ですが、標準について上記で述べたことを参照してください...

于 2009-12-02T20:29:51.213 に答える
3

特にテーブルが大きくなることが予想される場合は、あなたが思いついた式を個人的に書き留めます。関数呼び出しで列をラップすると、エンジンがそれらの列にあるインデックスを使用できなくなり、パフォーマンスが低下します。もちろん、小さなテーブルでは、これは問題にならないかもしれませんが、テーブルが大きくなってしまった場合に備えて、明示的な方法で行うのが好きです。

于 2009-12-02T20:32:06.220 に答える
1

このようなものをinformixで試すことができますか?

CASE
    WHEN a IS NULL AND B IS NULL THEN false 
    WHEN a IS NULL OR B IS NULL THEN true
    ELSE a <> B
END

IBM Informix Guide to SQL:Syntax、CASE Expressions

于 2009-12-02T20:39:02.933 に答える
0

IBM Informix Dynamic Serverは、さまざまな歴史的(別名「悪い」)理由から、ブール値についていくぶん独特の見方をしています。@astanderによって提案されたアイデアを採用すると、このCASE式は「機能します」が、私が最初に「明白ではない」と言います(参照-あなたがする前に言った!)。セットアップフェーズ:

create table x(a int, b int);
insert into x values(null, null);
insert into x values(null, 1);
insert into x values(1, null);
insert into x values(1, 1);
insert into x values(1, 2);

SELECTステートメント:

SELECT *
  FROM x
  WHERE   CASE
          WHEN a IS NULL AND b IS NULL THEN 'f'::BOOLEAN
          WHEN a IS NULL OR  b IS NULL THEN 't'::BOOLEAN
          WHEN a != b                  THEN 't'::BOOLEAN
          ELSE                              'f'::BOOLEAN
          END
;

このクエリの結果は次のとおりです。

                 1
      1           
      1          2

問題:

  • IDSは、FALSE、TRUE、またはUNKNOWNをキーワードとして認識しません。
  • IDSは、「a!= b」(または「a <> b」)などのブール式をそのように認識しません。

はい、これを述べなければならないのは私にとって非常に苦痛です。

于 2009-12-03T00:56:47.550 に答える
0

NULL がどのように処理されるかを確認したい場合は、Informix がサポートする NULL チェックを使用する必要があります。SE バージョンは COALESCE をサポートしていませんが、DECODE とおそらく CASE をサポートしています。

WHERE COALESCE(t.a, 0) != COALESCE(t.b, 0)
WHERE DECODE(NULL, 0, t.a) != DECODE(NULL, 0, t.b)
于 2009-12-02T20:30:01.043 に答える
0

SQL Server の場合は、次を使用します。

WHERE ISNULL(A, '') <> ISNULL(B, '')
于 2009-12-02T20:34:08.727 に答える
0

問題は、オペランドの一方または両方が NULL の場合にa<>b(or a=b) が生成され、 orが生成さNULLれないことです。isとis は句での選択のように動作するため、これはケースには関係ありません。10=NULL OR 11NULL OR 0NULL0WHERE

あなたは言えた:

a<>b OR (a IS NULL)<>(b IS NULL)

ただし、いずれかの方法で行う必要がある場合は、NULL を誤用している兆候である可能性があり、他の NOT NULL 値を使用してこの同等の条件を示すようにスキーマを変更することを検討する必要があります。

たとえばperson、列を持つテーブルがある場合title、タイトルがないことを示すために NULL を使用しないでください。それは「欠落している」データではなく、タイトルが存在しないだけです。''したがって、他の空の文字列と喜んで比較できる空の文字列として保存してください。(もちろん、空の文字列の問題でOracleを実行しない限り...)

于 2009-12-02T21:06:23.450 に答える
0

もしも

where ((A=B) OR (A IS NULL AND B IS NULL))

は平等のためです。なぜ使用しないのですか:

where NOT (
  ((A=B) OR (A IS NULL AND B IS NULL))
)

不平等のため?

于 2016-02-04T19:06:52.547 に答える