SQL嵌套不存在理解

时间:2015-11-21 19:20:52

标签: sql relational-division

我希望供应各部分的供应商的SIDS。我无法理解本书给出的查询答案。

Suppliers(sid: integer, sname: string, address: string)
Parts(pid: integer, pname: string, color: string)
Catalog(sid: integer, pid: integer, cost: real)

假设您获得了以下数据库:

表:零件

PID
P1
P2
P3

表:目录

SID  PID  
S1   P1
S1   P2
S1   P3
S2   P1

它应输出S1,但我相信在给定的查询中,它将输出S1和S2。最后一个嵌套查询不会满足SID = 2吗?因为如果C1.sid = S2并且C.sid = S2并且C1.pid = P1并且P.pid = P1那么它将满足查询。

书的答案如下: SQL翻译:“C.Sid,其中不存在C.Sid未提供的部分”

SELECT C.sid
FROM Catalog C
WHERE NOT EXISTS (SELECT P.pid
                  FROM Parts P
                  WHERE NOT EXISTS (SELECT C1.sid
                                    FROM Catalog C1
                                    WHERE C1.sid = C.sid
                                    AND C1.pid = P.pid)
                  )

3 个答案:

答案 0 :(得分:1)

一个简单的矛盾证明'将证明查询永远不会返回S2。

对于返回S2的查询,第一个NOT EXISTS将要求Parts上的子查询产生零行。但肯定不是这种情况,因为该特定子查询返回S2未提供的所有部分(即P2和P3)。

答案 1 :(得分:1)

您应该将查询读作:

向我提供那些没有高估供应商的相应目录的供应商。您应该在这里从上到下阅读查询。想象一下Catalogs表上的循环。获取第一行(S1,P1)。为Parts执行内循环,并检查S1是否存在该部分。它存在。好。获取第二部分。它存在。获取第三部分。它存在。因此,对于第一行,不存在第一行中供应商的目录中不存在的这样的部分。获取第二行(S1,P2)等...

答案 2 :(得分:0)

萨姆,你自己给了答案。

查询选择您在结果中不想要的sid(不存在的地方)。

所以查询选择S2(不是两者),因为你选择的所有sid都没有被选中,结果就是S1。

用简单的话说;你创建了一个你不想要最终结果的sid的列表。