为什么这个PostgreSQL查询会导致0个结果,即使我知道有
我的系统中有 2 个表:journal 和 journal_contribution。两者都有一个字段 uuid 作为主键,而 journal_contribution 包含字段 journal_uuid 以将其链接到日志。其他领域不重要。日志表有 461283 条记录,journal_contribution 有 336136 条记录。
我想确定我有多少期刊没有引用它们的 journal_contribution。
我的第一个想法是以下查询
select count(*)
from journal
where uuid not in
(select journal_uuid as uuid
from journal_contribution)
我知道这不是很好,但我很惊讶在 2 分钟后我得到了 0 结果。更重要的是,如果我在没有“not”的情况下运行相同的查询,我会得到结果 124121。如果我从期刊总数中减去这个,我预计原始结果是 337162。
当我将代码更改为以下更高性能的版本时,我确实得到了正确的结果,但我想首先了解 0。有人可以向我解释一下吗?
select count(*)
from journal
where not exists
(select 1
from journal_contribution jc
where jc.journal_uuid = journal.uuid)
这些查询是在运行 PostgreSQL 11 的 pgAdmin 4.21 中完成的
回答
我强烈建议您不要使用not in子查询。原因很简单: NULL值的处理不直观。
正如你所观察到的,NOT IN过滤掉所有的行,如果任何子查询返回的行都是NULL。
有一个简单的选择 not exists:
select count(*)
from journal j
where not exists (select 1
from journal_contribution jc
where jc.journal_uuid = j.uuid
);
此外,此查询可以使用 上的索引journal_contribution(journal_uuid)。我猜有了这样的索引,这个查询会相当快。