【问题标题】:Oracle select query does not fetch records where value is nullOracle 选择查询不获取值为空的记录
【发布时间】: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)

我对两者之间的区别感到困惑。

【问题讨论】:

    标签: oracle oracle11g


    【解决方案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中的概述
    猜你喜欢
    • 1970-01-01
    • 2019-06-10
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 2014-02-07
    • 1970-01-01
    相关资源
    最近更新 更多