繁体   English   中英

SQL案例给出不一致的结果

[英]SQL case giving inconsistent result

我从下面两个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 Null甚至不等于它自己。

但那又回归了什么呢?

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

再次0

SQLFiddle链接

因为NULL未知,这就是结果为0 当您想要比较列或值是否为null时,请使用IS NULLIS 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

将任何内容与NULL进行比较的结果,甚至本身,总是为NULL(不是TRUE或FALSE)。

搜索CASE表达式:

  • 如果没有Boolean_expression计算为TRUE,则数据库引擎在指定ELSE子句时返回else_result_expression,如果未指定ELSE子句则返回NULL值。

在您的情况下,结果始终为0,因为ELSE子句中为0

要为此添加一些扭曲,请尝试这样做:

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

这也返回0 Null甚至不等于它自己。

但那又回归了什么呢?

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

这又返回0 哦,神圣的......它甚至不等于它本身,而这不是等于自己......相当多的局面没有得到疯狂的把握...

为什么要牢记这一切? - 有人可能会问

一个例子是索引 :在Oracle中,索引不能像人们期望它们在NULL值上工作一样,其中列允许使用该值。 这意味着给定索引,如果索引中包含的行的所有值(字段,字段上的函数等) 都是 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 LASTNULLS FIRST修饰符(至少在Oracle中)设置排序顺序。 您观察到的是ORDER BY没有修饰符时的默认排序顺序

NULL是一个扭曲的业务,如果可能的话,明智地避开它......(这不仅适用于SQL,而且适用于OOP语言中的某些情况。)

您不能将<>或=与空值一起使用。 你需要说

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

这并不矛盾。 如果您有2个对象A,B,则为以下三个对象之一:

  • A等于B.

  • A不等于B.

  • 你不能比较A和B

就像检查(0/0> 0)还是(0/0 <0)还是(0/0 = 0)。 您只是无法比较它们。 每个选项都是假的

对于您的示例:案例检查您的参数是否为真

  • 参数('abc'= null)不为真,它为null

  • 参数('abc'<> null)不是真的,它是null

NULL值表示该列的数据值为Unknown。 NULL不与Zero同义,也不是零长度字符串或空白。

您与NULL进行比较的任何结果都将导致未知(NULL)。

请检查清除你的疑虑。 要获得正确的结果,请使用IS NULL或IS Not NULL,如您所知。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM