AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 244148
Accepted
Just a learner
Just a learner
Asked: 2019-07-31 10:25:59 +0800 CST2019-07-31 10:25:59 +0800 CST 2019-07-31 10:25:59 +0800 CST

集合为空时如何理解“NULL NOT IN”?

  • 772

这个问题中的 SQL 是针对 Oracle 的。但是您可以简单地删除FROM dual它以使其在 SQL Server 上工作(它返回与 Oracle 相同的结果)。

我有以下 SQL:

SELECT 1
FROM dual
WHERE NULL IN (SELECT 1 FROM dual WHERE 1 = 0);

SELECT 1
FROM dual
WHERE NULL NOT IN (SELECT 1 FROM dual WHERE 1 = 0);

分别返回一个空集和 1。当我们用其他值替换 时NULL,我们得到了完全相同的结果。

SELECT 1
FROM dual
WHERE 33 IN (SELECT 1 FROM dual WHERE 1 = 0);

SELECT 1
FROM dual
WHERE 33 NOT IN (SELECT 1 FROM dual WHERE 1 = 0);

那么NULL和空结果集的比较在这里是如何进行的呢?

sql-server oracle
  • 2 2 个回答
  • 785 Views

2 个回答

  • Voted
  1. Best Answer
    ypercubeᵀᴹ
    2019-08-01T23:15:22+08:002019-08-01T23:15:22+08:00

    让我们看看这两个条件会发生什么:

    WHERE NULL IN (SELECT 1 FROM dual WHERE 1 = 0);
    
    WHERE NULL NOT IN (SELECT 1 FROM dual WHERE 1 = 0);
    

    由于子查询产生一个空表,我们可以用伪代码编写它们:

    WHERE NULL IN (<empty_table>);
    
    WHERE NULL NOT IN (<empty_table>);
    

    所以第一个询问是否有一些(NULL)值在一个空表中。这种条件的结果总是FALSE,与值是否为 null 无关,因为表是空的。

    在第二个条件下应用相同的推理,它总是TRUE, 再次独立于值。

    在 Postgres 中很容易确认这些条件的结果值是什么,因为我们有一个布尔类型。请参阅dbfiddle.uk,其中第一个显示f(FALSE),第二个显示t(TRUE)。


    由于上述原因,当您运行两个查询时,它们变为:

    SELECT 1
    FROM dual
    WHERE FALSE ;
    

    给出空结果(正确,因为WHERE条件是FALSE)
    和

    SELECT 1
    FROM dual
    WHERE TRUE ;
    

    给出一行(再次正确)。

    • 5
  2. Chessbrain
    2019-07-31T10:58:52+08:002019-07-31T10:58:52+08:00

    这是SQL特有的所谓“三值逻辑”的问题。与使用 和 的其他编程语言不同TRUE,FALSESQL 还具有 UNKNOWN (NULL)。SQL 的不同元素处理 UNKNOWN 的方式也不一致。

    ON,WHERE并且HAVING都将 UNKNOWN 视为 FALSE。SQL 将空结果集视为 NULL。因此,NOT IN它正在寻找一个错误的陈述,并且由于 WHERE 将 NULL 解释为 FALSE,您会收到您的输出。比较两个 NULL 值也会返回 UNKNOWN。

    另一方面,CHECK约束将 NULL 视为 TRUE。例如,如果您要CHECK对高于零的销售额创建约束,则 NULL > 0 的计算结果为 UNKNOWN,但规则是约束不得计算为 FALSE,因此它最终为 TRUE。(根据 Lennart 的评论编辑)。

    详细解释:

    SELECT 1
    WHERE NULL IN (SELECT 1 WHERE 1 = 0);
    

    (SQL 服务器语法)

    返回一个空集,并且由于 SQL 将空数据集视为 NULL,因此您实际上在做的是:

    SELECT 1
    WHERE NULL IN (NullSet/EmptySet);
    

    更具体地说,你将它与一个所有行的表进行比较= NULL

    https://www.oreilly.com/library/view/sql-and-relational/9781449319724/ch12s07.html

    If a row subquery evaluates to an empty table, that empty table is coerced to a row of all nulls.

    你也有它的数学部分:

    http://www.solving-math-problems.com/null-set-empty-set.html

    比较两个 NULL 时,结果始终为 UNKNOWN,而 WHERE 语句将 UNKNOWN 视为 FALSE。

    因此,在您的第一个代码中:

    SELECT 1
    WHERE NULL IN (NullSet/EmptySet);
    

    您的 WHERE 语句基本上是检查 NULL 是否存在于 NULL 集合中,并且由于 NULL 的比较是 UNKNOWN 并且 UNKNOWN 被视为 FALSE,因此您不会得到任何结果。

    但在这儿:

    SELECT 1
    WHERE NULL NOT IN (NULL);
    

    您是说 NULL 集中不存在 WHERE NULL。同样,由于 UNKNOWN 被视为 FALSE,您会得到一个输出。

    这也解释了为什么当你比较:

    SELECT 1
    FROM dual
    WHERE 33 NOT IN (SELECT 1 FROM dual WHERE 1 = 0);
    

    您收到了输出。因为 33 不在 NULL Set/Empty Set 中的元素中。

    • 1

相关问题

  • ORDER BY 使用文本列的自定义优先级

  • 舒服的sqlplus界面?[关闭]

  • 如何在数据库中找到最新的 SQL 语句?

  • 如何使用正则表达式查询名称?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve