Oracle 选择查询不获取值为空的记录
Posted
技术标签:
【中文标题】Oracle 选择查询不获取值为空的记录【英文标题】:Oracle select query does not fetch records where value is null 【发布时间】:2020-10-06 15:40:20 【问题描述】:我有一个 oracle 数据库查询,我想从一个表中获取所有此类记录,其中 DECISION 的值 不等于丢弃。 我运行了以下查询:
select * from TABLE where DECISION != 'Discard'
我的数据库中有两条记录,但两者的 DECISION 均为空,不等于 DISCARD。但是,我没有得到任何记录。
所以,我不得不将查询更改为成功获取记录的下方。
select * from TABLE where (DECISION != 'Discard' or DECISION is null)
我对两者之间的区别感到困惑。
【问题讨论】:
【参考方案1】:根据设计/定义,NULL
是一个表示未知/不适用的特殊值。与NULL
进行的任何比较都是UNKNOWN
,在Oracle 的三值逻辑(https://en.wikipedia.org/wiki/Three-valued_logic)中既不是TRUE
,也不是FALSE
。
你的第一个谓词:
where DECISION != 'Discard'
对于具有NULL
决策的记录,评估为UNKNOWN
。 WHERE
子句仅包括谓词为 TRUE
的行。由于UNKNOWN
与TRUE
不同,您的第一个谓词不包括NULL
值。
你的第二个谓词:
where (DECISION != 'Discard' or DECISION is null)
计算为(UNKNOWN OR TRUE)
,而后者又计算为TRUE
。因此,您的第二个谓词包含 NULL
值。
【讨论】:
这是不正确,正如 here 所记录的那样。1 = null
是未知的并且不是假的。如果它是false,那么它的否定(NOT)将是true,它不是!请调整以免在已经令人困惑的逻辑中散布混乱;)【参考方案2】:
您可以使用NVL
select * from TABLE where NVL(DECISION,'x') != 'Discard'
“问题”在于三值 SQL 逻辑
如果 DECISION
为 NULL 比 DECISION != 'Discard'
返回的不是 TRUE
而是 UNKNOWN
(这意味着不知道 DECISION 是否为 Discard
)。
详情见Oracle Documentation
a != NULL 为 a 的任何值提供 UNKNOWN
要让所有行测试 可为空 列,您必须使用 NVL
或可能的 COALESCE
(= 更多“标准”)
【讨论】:
感谢您的解释。 @Ashish 不幸的是没有那么简单。 SQL 用TRUE
、FALSE
和UNKNOWN
实现了一个三值logik,所以你不能暗示不是true --> false。查看docs中的概述以上是关于Oracle 选择查询不获取值为空的记录的主要内容,如果未能解决你的问题,请参考以下文章
sql 子查询中部分数据有空值,怎么返回0,NULL+数字=null出来不可以
选择所有 3 列同时不为空的位置(Laravel 查询生成器)