我遇到了一个奇怪的问题,使用 NOT IN 对 PostgreSQL 数据库运行查询,但不明白为啥它不起作用

Posted

技术标签:

【中文标题】我遇到了一个奇怪的问题,使用 NOT IN 对 PostgreSQL 数据库运行查询,但不明白为啥它不起作用【英文标题】:I hit a weird issue running a query against a PostgreSQL Database using NOT IN and don't understand why it didn't work我遇到了一个奇怪的问题,使用 NOT IN 对 PostgreSQL 数据库运行查询,但不明白为什么它不起作用 【发布时间】:2021-01-08 19:27:11 【问题描述】:

我有一个带有 id 和 parent_id 列的分层表,parent_id 有一个指向 id 列的外键。每行只能有一个父级,但多行可以绑定到同一个父级。我想检索所有没有孩子的行。

我通过以下查询尝试了此操作

SELECT *
FROM table
WHERE id NOT IN (
    SELECT DISTINCT(parent_id)
    FROM table
)

这返回了 0 行。如果我将 NOT IN 更改为 IN,它会正确返回有子项的行(其他行与它通过他们的 parent_id)

我最终得到了这个工作:

SELECT *
FROM table
WHERE id NOT IN(
    SELECT id
    FROM table
    WHERE id IN (
        SELECT DISTINCT(parent_id)
        FROM table
    )
)

但我不明白为什么第一个查询不起作用?谁能帮我理解这里发生了什么?我不明白 NOT IN 应该如何工作吗?

【问题讨论】:

【参考方案1】:

试试

SELECT *
FROM table
WHERE id NOT IN (
    SELECT DISTINCT(parent_id)
    FROM table
    WHERE parent_id IS NOT NULL
)

例如:

with t(x) as (values(1),(2))
select 3
where 3 not in (select x from t);

┌──────────┐
│ ?column? │
├──────────┤
│        3 │
└──────────┘

但是

with t(x) as (values(1),(2),(null))
select 3
where 3 not in (select x from t);

┌──────────┐
│ ?column? │
├──────────┤
└──────────┘

这是因为DBMS无法做出决定是id = null还是不是(结果是undefined

您可以按照上述方法修复它或使用not exists

with t(x) as (values(1),(2),(null))
select 3
where not exists (select x from t where x = 3);

┌──────────┐
│ ?column? │
├──────────┤
│        3 │
└──────────┘

【讨论】:

以上是关于我遇到了一个奇怪的问题,使用 NOT IN 对 PostgreSQL 数据库运行查询,但不明白为啥它不起作用的主要内容,如果未能解决你的问题,请参考以下文章

记录gorm union和软删除一起使用遇到的一个奇怪问题

以编程方式使用 AddView 时奇怪的上边距

使用 1 Mb 堆的奇怪位图

Django Channels 给我一个奇怪的错误

奇怪的错误:未捕获的TypeError:非法调用ajax

使用 ErikEJ 的 SQL CE Membership 提供程序时出现奇怪的错误