[英]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
因为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
将任何内容与NULL进行比较的结果,甚至本身,总是为NULL(不是TRUE或FALSE)。
搜索CASE表达式:
在您的情况下,结果始终为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)
在仅包含正整数的列上,以便能够快速查询它们。 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中)设置排序顺序。 您观察到的是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.