在一次考试中,我被要求检索从未在鹿特丹运输过集装箱的运输商的名称。正确答案是
select Transporter.ID
from Transporter
where Transporter.ID not in (
select TransporterID
from Container
inner join Transportation on Container.ID = Transportation.ContainerID
where Container.City = 'Rotterdam')
然而,以下内容被标记为错误答案:
select Transporter.ID
from Transporter
where Transporter.ID in (
select TransporterID
from Container
inner join Transportation on Container.ID = Transportation.ContainerID
where Container.City <> 'Rotterdam')
为什么两个语句都不导致相同的结果? in ( ... where A <> B )
和not in ( ... where A = B )
之间的实际区别是什么?
[请注意,Transportation
位于关系方案的中心,其所有主要属性都是外键]
答案 0 :(得分:2)
让我们构建一个简单的表作为示例:
容器
!
然后查询
TransporterID | City
1 | 'Rotterdam'
1 | 'Paris'
2 | 'Rotterdam'
这将得到1(巴黎行)
然后,SELECT TransporterID
FROM Container
WHERE Container.City <> 'Rotterdam'
语句将给出错误的结果(运输工具1已到达“鹿特丹”)
答案 1 :(得分:1)
除了其他答案指出的内容之外,还请考虑NULL
:
如果City
为NULL
,则两个查询在其FALSE
子句中将比较视为WHERE
...
答案 2 :(得分:0)
您的版本正在回答一个稍微不同的问题:“在鹿特丹以外的其他地方运输过集装箱的运输商的身份证是什么?”
关于最佳答案,我将使用obj
(重要)和表别名(更具风格):
not exists
select t.ID
from Transporter t
where not exists (select 1
from Container c join
Transportation tr
on c.ID = t.ContainerID
where tr.TransporterID = t.id and
c.City = 'Rotterdam'
);
的行为与大多数人期望的不同,子查询中的任何行返回NOT IN
(在这种情况下,所有行都被过滤掉)。 NULL
具有预期的行为。