2

以下の2つのSQLクエリから一貫性のない結果が得られます。

Query1:select (case when 'Abc' = null then 1 else 0 end) from dual

Query2:select (case when ('Abc' <> null) then 1 else 0 end) from dual

両方のクエリの結果は同じです。 0

何が問題なのですか?

注:: 使用できることはわかっていますIS NULL and IS NOT NULLが、私の質問は、上記のクエリの結果に一貫性がない理由です。

編集:@ppeterkaの回答から追加。

select (case when null = null then 1 else 0 end) from dual

これも戻り0ます。ヌルはそれ自体と同じではありません。

しかし、これは何を返しますか?

select (case when null <> null then 1 else 0 end) from dual

0また

SQLFiddleリンク

4

6 に答える 6

4

NULL不明なため、結果は0です。列または値がnullであるかどうかを比較する場合は、またはを使用しIS NULLますIS NOT NULL

select (case when 'Abc' IS null then 1 else 0 end) from dual       -- 0
select (case when ('Abc' IS NOT null) then 1 else 0 end) from dual -- 1
于 2013-03-22T09:59:36.690 に答える
2

何かをNULLと比較した結果は、それ自体であっても、常にNULLになります(TRUEまたはFALSEではありません)。

検索されたCASE式:

  • ブール式がTRUEと評価されない場合、データベースエンジンは、ELSE句が指定されている場合はelse_result_expressionを返し、ELSE句が指定されていない場合はNULL値を返します。

あなたの場合、ELSE句の0であるため、結果は常に0になります。

于 2013-03-22T10:18:44.167 に答える
1

これに少しひねりを加えるには、これを試してみてください。

select (case when null = null then 1 else 0 end) from dual

これも戻り0ます。ヌルはそれ自体と同じではありません。

しかし、これは何を返しますか?

select (case when null <> null then 1 else 0 end) from dual

これがまた戻ってきます0!ああ聖なる...それはそれ自体と等しくない間、それはそれ自体と等しくさえありません...それは狂気にならずに把握するためのかなりの状況...

なぜこれをすべて覚えているのですか?-尋ねるかもしれません

1つの例は索引付けNULLです。Oracleでは、列がその値の使用を許可している場合、索引は値に対して機能すると予想されるようには機能しません。これは、インデックスが与えられた場合、インデックスに含まれる行のすべての値(フィールド、フィールド上の関数など)がすべて NULLである場合、その行はその指定されたインデックスでインデックス付けされないことを意味します。つまり、これは、インデックスが付けられた値が1つだけのインデックス(たとえば、フィールドが直接)の場合、null値は、その行がインデックスに含まれないことを意味します。

これを克服するには

  • 正の整数のみを含む列のように、意味を意味的に表す明確で正確な値NULLを持つインデックスを追加して、それらをすばやくクエリできるようにすることをお勧めします。NVL(mynullcol,-1)
  • または、定数値を追加して「半複数値」インデックスを作成することもできます。このインデックスは、すべての行にインデックスを付けます。一方は定数であるため、一方はnullになります。(create index idx_myindex on table(column_with_nulls,1);

この質問この記事では、この主題についてもう少し詳しく説明します)

別の例は注文です...

select (case when null < null then 1 else 0 end) from dual;
select (case when null > null then 1 else 0 end) from dual;

両方0。これは大丈夫です...私たちは今までにこれを期待していました...そしてこれはどうですか?

select (case when 'Abc' > null then 1 else 0 end) from dual;
select (case when null > 'Abc' then 1 else 0 end) from dual;

うーん...また両方0。これは問題になる可能性があります-注文はどのように機能しますか?

select col_1 from
(select null as col_1 from dual)
union all (select 'Abc' as col_1 from dual)
union all (select null as col_1 from dual)
union all (select null as col_1 from dual)
order by col_1 

ただし、これは一貫して次のようになります。

Abc
null
null
null

... order by col_1 DESC返品の使用:

null
null
null
Abc

したがって、これから、経験的に、それはそう思われ'Abc' < nullます...しかし、@ ypercubeの貴重なコメントによると:

NULLS LASTソート順は、およびNULLS FIRST修飾子を使用して設定できます(少なくともOracleでは)。観察されるのは、ORDERBYに修飾子がない場合のデフォルトのソート順です。

NULLねじれたビジネスであるため、可能であればそれを回避するのが賢明です...(これは、SQLだけでなく、OOP言語の特定の状況にも当てはまります。)

于 2013-03-22T10:19:42.110 に答える
0

<>または=をnullで使用することはできません。あなたは言う必要があります

select (case when 'Abc' is null then 1 else 0 end) from dual

select (case when 'Abc' is not null then 1 else 0 ) from dual
于 2013-03-22T10:00:06.790 に答える
0

矛盾はありません。オブジェクトA、Bが2つある場合は、次の3つのいずれかになります。

  • AはBに等しい

  • AはBと等しくない

  • AとBを比較することはできません

これは、(0/0> 0)または(0/0 <0)または(0/0 = 0)かどうかを調べるようなものです。それらを比較することはできません。すべてのオプションはfalseです

あなたの例の場合:caseはあなたの議論が真であるかどうかをチェックします

  • 引数('abc' = null)は真ではなく、nullです

  • 引数('abc' <> null)は真ではなく、nullです

于 2013-03-22T10:20:15.840 に答える
0

値NULLは、列のデータ値が不明であることを意味します。NULLは、ゼロ、長さゼロの文字列または空白と同義ではありません。

NULLと比較すると、不明(NULL)になります。

疑問を解消するには、これを確認してください。正しい結果を得るには、すでに知っているようにISNULLまたはISNotNULLを使用します。

于 2013-03-22T10:40:48.300 に答える