我的查询行为方式与其他方式无关。
我有两个表,stagin_users
和users
。在这两个表中,我都有一个名为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
。
答案 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往往本质上不安全。有关详细信息,请参阅以下链接。