【问题标题】:Why does SQL NOT EXISTS return 1 record of all NULL values为什么 SQL NOT EXISTS 返回所有 NULL 值的 1 条记录
【发布时间】:2015-05-19 04:39:37
【问题描述】:

SQL Fiddle 如下:

create table tbl( col1 int, col2 int, col3 int);
insert into tbl values(1,1,1);
insert into tbl values(1,1,1);

select sum(col1) c1, sum(col2) c2, sum(col3)c3
from tbl
where not exists (
  select 2 as c1, 2 as c2, 2 as c3
  )

我希望这会返回 0 条记录。相反,它返回 1 条空值记录。你能告诉我为什么吗?

附:我试图理解不存在的行为。

【问题讨论】:

    标签: mysql sql not-exists


    【解决方案1】:

    这与EXISTS 无关。您的NOT EXISTS 计算结果为FALSE,因为SELECT 2 AS c1, 2 AS c2, 2 AS c3 总是返回一行。这意味着您的查询相当于:

    SELECT SUM(col1) c1, SUM(col2) c2, SUM(col3) c3 FROM tbl WHERE 0
    

    也就是说,这实际上是关于SUM 语义。 SUM 即使在一个空集中也应该返回一个值,在这种情况下的值是NULL

    来自mysql documentation

    SUM(expr)

    返回 expr 的总和。如果返回集没有行,SUM() 返回 NULL。

    如果没有匹配的行,SUM() 返回 NULL。

    【讨论】:

    • 哦,我想我现在明白你在说什么了...... select 什么都不返回,但 SUM 函数会创建空值......?
    【解决方案2】:

    除了JuniorCompressor 指出的以外,注意查询中SQL 子句的执行顺序也很重要。 WHERE 首先运行,然后是 SELECT 列表,其中在一个空结果集上计算聚合,结果为 null,因为它们没有要处理的东西。

    要按预期实际丢弃该结果,您需要一个 HAVING 子句,该子句随后运行,并且可以根据聚合结果过滤掉。

    区别很微妙,但说明了这个问题的全部意义。 WHERE 决定哪些原始行有资格集成聚合。 HAVING 决定将哪个聚合结果包含在最终结果中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-04
      • 2018-12-22
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      相关资源
      最近更新 更多