在询问不在空集中的项目时返回空集

时间:2014-08-28 16:41:27

标签: mysql

我的查询行为方式与其他方式无关。

我有两个表,stagin_usersusers。在这两个表中,我都有一个名为name的列。在users表格中,name的每个值均为NULL。在staging_users中,我有13行没有NULL值。我正在尝试运行一个查询,其中我获取了临时表中名称不在users表中的所有用户。

我写的查询是:

SELECT name FROM staging_users WHERE name NOT IN (SELECT name FROM users);

在编写查询时,我得不到任何结果。这种行为的原因是什么?

由于users表只有NULL值,我知道我可以说WHERE name IS NOT NULL并且我会得到相同的结果,但我希望这个查询能够对付表中的值,这一切都发生了成为NULL

2 个答案:

答案 0 :(得分:3)

来自docs

  

为了符合SQL标准,IN不仅在左侧的表达式为NULL时返回NULL,而且如果在列表中找不到匹配且列表中的一个表达式为NULL,则返回NULL。

并且

  

expr NOT IN (value,...)NOT (expr IN (value,...))相同。

因此,当SELECT NULL值为NOT IN时,NULL会返回SELECT name FROM staging_users WHERE name IS NOT NULL AND name NOT IN ( SELECT name FROM users WHERE name IS NOT NULL ); ..所以没有行匹配。

你可以这样纠正:

   SELECT su.name 
     FROM staging_users su
LEFT JOIN users u
       ON u.name = su.name
      AND su.name IS NOT NULL
      AND u.name IS NOT NULL;

或者,同样的逻辑:

{{1}}

作为一个额外的注释,我会认真地质疑允许用户使用NULL名称的数据结构..如果更改了原始查询将会有效。

答案 1 :(得分:1)

对于此类查询,

NOT EXISTS通常是更好的选择。使用可能的NULL值时,NOT IN往往本质上不安全。有关详细信息,请参阅以下链接。

https://dba.stackexchange.com/questions/17407/why-does-not-in-with-a-set-containing-null-always-return-false-null