2015-10-31 100 views
0

我有表:SQL相关同桌的子查询

Person(SSN, name, address) 
Car(license, year, model) 
Accident(license, accident-date, driver, damage-amount) 
Owns(SSN, license) 

问题问:

查找已参与了超过一个意外的所有汽车的牌照号码(不返回DUPLICATES )。

答案之一是:

SELECT DISTINCT A1.license 
FROM Accident A1 
WHERE A1.license IN (SELECT A2.license 
        FROM Accident A2 
        WHERE A1.accident-date <> A2.accident-date) 

它从未将检查A1.license = A2.license在相关子查询。因此,据我了解,即使两个元组拥有不同的许可证,子查询也会检查A1中的元组是否具有与A2中的元组不同的事件日期。所以这不应该是错误的?

编辑:它假定一辆汽车在一天中不能有多个事故。

+1

这个“答案”显然是错误的,如果'Accident'中有多个日期,它将返回* all *行。正如你所说的那样,缺少'AND A1.license = A2.license'。 – dnoeth

+0

哪种RDBMS适用于?请添加一个标签来指定您是使用'mysql','postgresql','sql-server','oracle'还是'db2' - 或者其他的东西。 –

+0

这个问题没有指定,但由于我的课是学习只是MySQL,我已经标记了mysql。 –

回答

1

其实IN运营商正在检查许可证的平等。让我们做一个测试。说Accidents表包含行:对外部查询的每一行

License AccidentDate 
L1  20151001 
L1  20151020 
L2  20151025 

相关子查询进行评估。想象一下遍历行的游标。对于row1A.LicenceL1。内部子查询只检查与20151001不同的日期,它会发现row2row3(L1, L3)。所以A.LicenceL1是在内部子查询的结果集中,它将返回最终结果。所以做第二行。但不包括row3,因为20151025之后的日期中没有L2。所以查询是正确的。

+0

为什么第3行不会从子查询中返回?在子查询中,我们从不检查A1.license = A2.license。因此,子查询会比较row3的日期和row1的日期,并且日期不同,因此它会返回,不是吗? –

+1

不,子查询将外部查询当前行的日期与日期进行比较。 Where子句将消除IN谓词评估为false的所有行。现在想象一下,在外部查询中,您位于row3的位置。 L2 20151025.内部子查询呢?它会筛选日期与20151025之外的其他日期,并发现20151001和20151020,但都是L1,因此当您处于排名第3行时,您将获得L2 IN(L1)。所以谓词是错误的,第3行被删除。 –

+1

用文字说出来:给我一些意外的行,其中许可证编号可以在一组许可证号码中找到,其中的日期与我的崩溃日期不同。如果我能找到与其他日期相同的一组,则意味着该车处于多次碰撞事故中。 –