PostgreSQL'NOT IN'和子查询

sko*_*ine 82 postgresql subquery

我正在尝试执行此查询:

SELECT mac, creation_date 
FROM logs 
WHERE logs_type_id=11
AND mac NOT IN (select consols.mac from consols)
Run Code Online (Sandbox Code Playgroud)

但我没有结果.我测试了它,我知道语法有问题.在MySQL中,这样的查询非常有效.我添加了一行以确保表mac中不存在一行consols,但仍然没有给出任何结果.

Mar*_*ers 145

使用NOT IN时,应确保没有值为NULL:

SELECT mac, creation_date 
FROM logs 
WHERE logs_type_id=11
AND mac NOT IN (
    SELECT mac
    FROM consols
    WHERE mac IS NOT NULL -- add this
)
Run Code Online (Sandbox Code Playgroud)

  • @wildplasser我不知道这件事.它不适用于我,直到我添加了"IS NOT NULL".嵌套的`SELECT`返回了一些`NULLS`,这就是IN跳过`IN(SELECT ...)`. (7认同)
  • 似乎在`NOT IN`子句中使用`NULL`不起作用,因为与`NULL`的比较既不是真也不是假.http://www.sqlbadpractices.com/using-not-in-operator-with-null-values/ (7认同)
  • 注意:不需要子查询中的`WHERE mac IS NOT NULL`子句,因为`In(...)`总是删除NULL(和重复).因为一个集合不能包含NULL (4认同)
  • 我非常感谢为什么`IS NOT NULL`导致这个工作的解释. (2认同)
  • 我将把我的声音添加到注意到如果没有“is not null”查询不会返回任何行的组中,但是当添加“is not null”时我会得到所需的值。很好的答案。 (2认同)
  • 如果子查询不产生匹配值且至少有一个"null"值,则查询将在没有"is not null"的情况下返回任何行.来自[第9.22节](https://www.postgresql.org/docs/current/static/functions-subquery.html#FUNCTIONS-SUBQUERY-NOTIN)的当前(第10版)PostgreSQL手册:"[...]如果有的话没有相等的右手值,并且至少有一个右手行产生null,NOT IN构造的结果将为null,而不是真的." (2认同)

wil*_*ser 27

使用NOT IN时,您还应该考虑NOT EXISTS,它以静默方式处理空案​​例.

SELECT mac, creation_date 
FROM logs lo
WHERE logs_type_id=11
AND NOT EXISTS (
  SELECT *
  FROM consols nx
  WHERE nx.mac = lo.mac
  );
Run Code Online (Sandbox Code Playgroud)

  • 还要注意,使用`NOT EXISTS`与`... NOT IN`会导致巨大的性能损失。 (2认同)
  • 在子查询的情况下,使用 NOT IN 而不是 NOT EXISTS 也有性能提升。见 https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_NOT_IN (2认同)

Fra*_*ens 6

您还可以使用LEFT JOIN和IS NULL条件:

SELECT 
  mac, 
  creation_date 
FROM 
  logs
    LEFT JOIN consols ON logs.mac = consols.mac
WHERE 
  logs_type_id=11
AND
  consols.mac IS NULL;
Run Code Online (Sandbox Code Playgroud)

"mac"列上的索引可能会提高性能.