我有一个嵌套的Not Exists,并且想知道它是否是双重否定。如果我删除这两个否定,如果它是等效的查询?
Suppliers(sid: integer, sname: string, address: string)
Parts(pid: integer, pname: string, color: string)
Catalog(sid: integer, pid: integer, cost: real)
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)
)
删除否定:" C.Sid提供每个部分"
SELECT C.sid
FROM Catalog C
WHERE EXISTS (SELECT P.pid
FROM Parts P
WHERE EXISTS (SELECT C1.sid
FROM Catalog C1
WHERE C1.sid = C.sid
AND C1.pid = P.pid)
)
答案 0 :(得分:4)
以下是SQLFiddle,您可以在其中测试以下查询:
第一个:
SELECT * FROM Catalog C
WHERE NOT EXISTS (SELECT P.pid FROM Part P
WHERE NOT EXISTS (SELECT C1.sid FROM Catalog C1
WHERE C1.sid = C.sid
AND C1.pid = P.pid) );
sid pid
1 1
1 2
2 1
2 2
备选方案(您可以看到结果现在等效):
SELECT * FROM Catalog C
WHERE EXISTS (SELECT P.pid FROM Part p
WHERE EXISTS (SELECT C1.sid FROM Catalog C1
WHERE C1.sid = C.sid
AND C1.pid = P.pid) );
sid pid
1 1
1 2
2 1
2 2
3 1
3 3
经典的数据库课程练习:
-- Suppliers for which doesn't exists any part that they doesn't provide.
SELECT * FROM supplier S
WHERE NOT EXISTS ( SELECT * FROM part P
WHERE NOT EXISTS ( SELECT * FROM catalog C
WHERE S.sid = C.sid
AND P.pid = C.pid ) );
sid name
1 "Dath Vader"
2 "Han Solo"
解析上述查询的一部分可能会让您更好地了解查询中涉及的逻辑。
SELECT * FROM part P
WHERE NOT EXISTS ( SELECT * FROM catalog C
WHERE P.pid = C.pid
AND C.sid = 3); -- R2D2 Here!
pid name
2 "Laser Gun"
R2D2被排除在结果集之外,因为它是唯一一个销售未在零件表中列出的产品的人。 该行的存在将RD2D从最终结果集中排除。
答案 1 :(得分:1)
您的第二个查询是C.Sid
,他提供了目录中的部件。
没有"所有"在查询中。这两个问题完全不同。
答案 2 :(得分:1)
不确定您的问题是否具有教育意义,或者您正在寻求更好的方法来解决您的问题。
如果您知道每个供应商销售多少零件,并知道有多少零件。很容易比较这些值。
SELECT C.Sid
FROM Catalog C
GROUP BY C.Sid
HAVING COUNT(pid) = (SELECT COUNT(P.pid)
FROM Parts P)