在我看来,这两个sql语句是等价的。
我的理解是:
第一个我从tmpPerson中提取所有行并过滤它们没有等效的人ID。此查询返回211条记录。
第二个人说给我所有身份不正确的tmpPersons。这将返回null。
显然,它们不相同或者它们具有相同的结果。我错过了什么?感谢
select p.id, bp.id
From person p
right join(
select distinct id
from tmpPerson
) bp
on p.id= bp.id
where p.id is null
select id
from tmpPerson
where id not in (select id from person)
我从第一个结果集中提取了一些ID,并在Person中找不到匹配的记录,所以我猜第一个是准确的,但我仍然感到惊讶他们不同
答案 0 :(得分:2)
我更喜欢left join
s到right join
s,所以让我们将第一个查询写为:
select p.id, bp.id
From (select distinct id
from tmpPerson
) bp left join
person p
on p.id = bp.id
where p.id is null;
(首选项是因为结果集保留了第一个表中的所有行而不是 last 表中的所有行。在阅读from
子句时,我马上就知道第一张桌是什么了。)
第二个是:
select id
from tmpPerson
where id not in (select id from person);
由于两个原因,这些并不相同。在您的情况下,最可能的原因是您在tmpPerson
中有重复的ID。第一个版本删除重复项。第二个没有。通过将distinct
放在正确的位置可以很容易地解决这个问题。
更微妙的原因与not in
的语义有关。如果任何 person.id
的值为NULL
,则会过滤掉所有行。我不认为您的查询就是这种情况,但这是有区别的。
我强烈建议您使用not exists
代替not in
,原因如上所述:
select tp.id
from tmpPerson tp
where not exists (select 1 from person p where p.id = tp.id);
答案 1 :(得分:1)
select id
from tmpPerson
where id not in (select id from person)
如果tmp person中有空id,则不会在此查询中捕获它们。但在您的第一个查询中,它们将被捕获。所以使用isnull将解决问题
where isnull(id, 'N') not in (select id from person)