关系代数除法sql等价

关系代数除法sql等价,sql,Sql,我很难理解关系代数除法的sql等价物的翻译。我正在努力寻找供应每一个零件的供应商的SID。在嵌套查询中,它本质上是在声明它正在寻找所有不提供所有零件且不存在零件的供应商吗? 但是,C1.sid=C.sid和C1.pid=P.pid的条件是否也针对实际供应每个零件的供应商的sid Suppliers(sid: integer, sname: string, address: string) Parts(pid: integer, pname: string, color: string) Cata

我很难理解关系代数除法的sql等价物的翻译。我正在努力寻找供应每一个零件的供应商的SID。在嵌套查询中,它本质上是在声明它正在寻找所有不提供所有零件且不存在零件的供应商吗? 但是,C1.sid=C.sid和C1.pid=P.pid的条件是否也针对实际供应每个零件的供应商的sid

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

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)
                  )

在直接回答您的问题之前,让我先告诉您应该如何翻译问题。让我们首先将外部子查询作为一个整体来看:

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子句中的列实际上没有任何意义。我们基本上可以像下面这样编写查询,但仍然传达完全相同的含义,因此您不必担心C1.sid在最内层查询中的含义

SELECT P.pid
FROM Parts P
WHERE NOT EXISTS (
     SELECT *
     FROM Catalog C1
     WHERE C1.sid = C.sid
     AND C1.pid = P.pid)
现在涉及到主查询

SELECT C.sid
FROM Catalog C
WHERE NOT EXISTS (SELECT *
                  FROM Parts P
                  WHERE NOT EXISTS (SELECT *
                                    FROM Catalog C1
                                    WHERE C1.sid = C.sid
                                    AND C1.pid = P.pid)
                  )
这意味着我们需要的是不存在其部件的供应商C.sid C.sid注意,我从上面的段落复制了子查询的翻译。这基本上意味着我们需要提供每个零件的供应商

现在回到你的两个问题:

在嵌套查询中,它本质上是在声明它正在查找 不提供所有零件且不存在供应商的所有供应商

不,请看上面的解释

但是C1.sid=C.sid和C1.pid=p.pid的条件 还针对实际供应每个零件的供应商的sid


查看与主查询相关的最内部查询不是正确的方法。这个最里面的查询用于第一个子查询来选择我们想要的部分。此处选择的供应商不相关,如上面用*替换所示。

似乎出现了双重否定。为什么不把所有不存在的改变为存在呢?示例:从目录C中选择C.sid,其中存在从零件P中选择*,其中存在从目录C1中选择*,其中C1.sid=C.sid和C1.pid=P.pid这是不同的。这意味着只有供应至少一个零件的供应商。不存在两次并不总是意味着双重否定,因为您对不同的表/列执行这些操作。你有没有试过用基本的关系代数运算——投影、选择、差分、笛卡尔积、重命名——重写C÷P?您将看到结果有两个差分运算符。不能将两个不同的运算符折叠为一或零。这相当于无法折叠两个连续的不存在查询。