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
)等...
我想要供应每个零件的供应商的 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
)等...