要为此添加一些扭曲,请尝试以下操作:
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
在列允许使用该值的值上工作的方式不同。这意味着给定一个索引,如果索引中包含的行的所有值(字段、字段上的函数等)都是all 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
andNULLS FIRST
修饰符设置排序顺序(至少在 Oracle 中)。当 ORDER BY 没有修饰符时,您观察到的是默认排序顺序
NULL
是一个扭曲的业务,如果可能的话,明智的做法是远离它......(这不仅适用于 SQL,而且适用于 OOP 语言的某些情况。)