SQL双重否定与不存在

时间:2015-11-20 18:10:05

标签: sql logic

我有一个嵌套的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)
                  )

3 个答案:

答案 0 :(得分:4)

不,操作并不等同。你想要实现它的东西相当于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被排除在结果集之外,因为它是唯一一个销售未在零件表中列出的产品的人。 该行的存在将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)