SQL嵌套不存在理解

SQL nested not exist understanding

我想要供应每个零件的供应商的 SIDS。我无法理解书中给出的查询答案。

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

假设您有一个数据库如下:

Table:零件

PID
P1
P2
P3

Table:目录

SID  PID  
S1   P1
S1   P2
S1   P3
S2   P1

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

书上给出答案如下: SQL 翻译:"C.Sid for which Does not exist the parts that are not supplied by 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)
                  )

Sam,你自己给出了答案。

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

因此查询选择了 S2(不是两者)并且因为您选择的所有 sid 都没有被选中,所以结果是 S1。

简单来说;您正在创建一个列表,其中包含您不希望出现在最终结果中的 sid。

一个简单的 'proof by contradiction' 将演示查询永远不会 return S2.

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

您应该将查询解读为:

请提供不存在上述供应商没有相应目录的零件的供应商。您应该在此处从上到下阅读查询。想象一下 Catalogs table 上的循环。获取第一行(S1,P1)。为 Parts 做一个内部循环并检查 S1 是否存在该部分。它存在。好的。获取第二部分。它存在。获取第三部分。它存在。因此,对于第一行,不存在第一行供应商目录中不存在的部分。获取第二行(S1,P2)等...