不存在,未显示 SQL Server 2015 查询假定的结果



我知道这个问题可能回答了太多次,但我找不到发生这种情况的原因。

我有 2 个表,我正在尝试从表 2 中选择表 1 中不存在的行,但是当我运行该查询时,即使我 100% 确定表 1 中有行不在表 2 中,它也没有显示任何结果。我的查询类似于以下内容:

select pid from tbl1 where not exists ( select pid from tbl2)

我知道还有其他方法可以实现这一点,我只是想了解为什么它不起作用的概念。

谢谢。

NOT EXISTS检查子查询中是否没有行。您的子查询应该是相关的,但由于它不是相关的,它的行为不会像您期望的那样。

实际上,如果您的子查询选择任何行,则不满足条件,并且谓词对所有行都失败。这意味着,您的查询根本不会返回任何行。

查询返回行的唯一情况是表tbl2为空。

解决方案#1:使用IN

现在,您可以使用此处显示的其他答案的相关子查询,也可以改用IN(如果tbl2永远不会有空值)。例如:

select pid from tbl1 where pid not in (select pid from tbl2)

解决方案#2:使用EXCEPT

select pid from tbl1
except
select pid from tbl2

解决方案#3:使用反联接

select a.pid
from tbl1 a
left join tbl2 b on b.pid = a.pid
where b.pid is null

你需要一个相关子句:

select pid
from tbl1
where not exists (select 1 from tbl2 where tbl2.pid = tbl1.pid)
-------------------------------------------^ correlation clause

子查询返回的列无关紧要 - 重要的是它是否返回行。 关联子句执行您想要的操作。 在您的情况下,如果tbl2有任何行,则子查询返回一行,NOT IN返回 false。

您可能会将NOT EXISTSNOT IN混淆。 也就是说,我强烈建议使用NOT EXISTS而不是NOT IN.

你也可以使用IN子句,

select pid from tbl1 where pid  not in ( select pid from tbl2)

如果要使用exists则需要定义连接条件

select pid from tbl1 where not exists ( select pid from tbl2 where tbl2.pid = tbl1.pid)

最新更新