SQL 与 Not exists 的双重否定
SQL double negation with Not exists
我有一个嵌套的 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 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)
)
删除否定:"C.Sid who supply every part"
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)
)
您的第二个查询是 C.Sid
谁提供目录中的零件。
查询中"all"没有任何意义。这两个查询完全不同。
不确定您的问题是否只是教育性的,或者您是在寻求更好的方法来解决您的问题。
如果你知道每个供应商卖多少零件,知道有多少零件。比较这些值很容易。
SELECT C.Sid
FROM Catalog C
GROUP BY C.Sid
HAVING COUNT(pid) = (SELECT COUNT(P.pid)
FROM Parts P)
不对,操作不等价。您要实现的目标相当于 SQL.
中的 algebra division operation
这是一个 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 被排除在结果集中,因为它是唯一销售未在部分 table 中列出的产品的产品。
此行的存在从最终结果集中排除了 RD2D。
我有一个嵌套的 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 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)
)
删除否定:"C.Sid who supply every part"
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)
)
您的第二个查询是 C.Sid
谁提供目录中的零件。
查询中"all"没有任何意义。这两个查询完全不同。
不确定您的问题是否只是教育性的,或者您是在寻求更好的方法来解决您的问题。
如果你知道每个供应商卖多少零件,知道有多少零件。比较这些值很容易。
SELECT C.Sid
FROM Catalog C
GROUP BY C.Sid
HAVING COUNT(pid) = (SELECT COUNT(P.pid)
FROM Parts P)
不对,操作不等价。您要实现的目标相当于 SQL.
中的 algebra division operation这是一个 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 被排除在结果集中,因为它是唯一销售未在部分 table 中列出的产品的产品。 此行的存在从最终结果集中排除了 RD2D。