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 决策的记录,评估为UNKNOWNWHERE 子句仅包括谓词为 TRUE 的行。由于UNKNOWNTRUE 不同,您的第一个谓词不包括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 用TRUEFALSEUNKNOWN 实现了一个三值logik,所以你不能暗示不是true --> false。查看docs中的概述

以上是关于Oracle 选择查询不获取值为空的记录的主要内容,如果未能解决你的问题,请参考以下文章

sql 子查询中部分数据有空值,怎么返回0,NULL+数字=null出来不可以

excel 怎样筛选出 有一个值为空的行

选择所有 3 列同时不为空的位置(Laravel 查询生成器)

Oracle中查询某字段不为空的SQL语句怎么写

oracle 我有1000条查询语句,通过执行每一条sql语句,返回所有的查询结果为空的记录,能实现吗?

Firestore 选择不为空的位置