简体   繁体   English

这两个SQL语句之间的实际区别是什么?

[英]What is the practical difference between these two SQL statements?

In an exam I was asked to retrieve the name of the transporters never having transported a container based in Rotterdam. 在一次考试中,我被要求找回从未在鹿特丹运输过集装箱的运输者的名字。 The correct answer was 正确答案是

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')

and nevertheless the following was marked as a wrong answer: 但是,以下内容被标记为错误答案:

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')

Why don't both statements lead to the same result? 为什么两个语句都不会导致相同的结果? What is the practical difference between in ( ... where A <> B ) and not in ( ... where A = B ) ? in ( ... where A <> B )not in ( ... where A = B )之间的实际区别是什么?

[Note that Transportation is in the center of the relational scheme, with all its prime attributs being foreign keys] [请注意, Transportation是关系计划的中心,其所有主要属性都是外键]

Let's build a simple table as example : 让我们构建一个简单的表格作为示例:

Container 容器

TransporterID | City
 1            | 'Rotterdam'
 1            | 'Paris'
 2            | 'Rotterdam'

And then this query 然后这个查询

SELECT TransporterID
FROM Container
WHERE Container.City <> 'Rotterdam'

This will result 1 (the row with paris) 结果将为1(巴黎行)

Then, WHERE Transporter.ID IN ( ... statement will give wrong result (transporter 1 has been to 'Rotterdam') 然后, WHERE Transporter.ID IN ( ...语句将给出错误的结果(运输者1已到达“鹿特丹”)

Besides what the other answers point out, take NULL s into consideration: 除了其他答案指出的以外, NULL考虑NULL

If City is NULL both queries would treat the comparison as FALSE in their WHERE clause... 如果CityNULL两个查询都将在WHERE子句中将比较视为FALSE ...

You version is answering a slightly different question: "What are the ids of transporters that have transported a container somewhere other than Rotterdam?". 您的版本正在回答一个稍有不同的问题:“将集装箱运输到鹿特丹以外的其他地方的运输商的ID是什么?”。

As for the best answer, I would use not exists (which is material) and table aliases (more stylistic): 至于最佳答案,我将使用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 does not behave the way most people expect when any row in the subquery returns NULL (all rows are filtered out in that case). 当子查询中的任何行返回NULL (在这种情况下,所有行都被过滤掉)时, NOT IN行为都不符合大多数人的期望。 NOT EXISTS has the expected behavior. NOT EXISTS具有预期的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM