嵌套 SQL 查询,每次嵌套实际发生了什么?

rra*_*azd 4 mysql database

我想知道这个查询是如何工作的:

SELECT empname FROM Employee WHERE not exists (
    SELECT projid FROM Project WHERE not exists (
        SELECT empid, projid FROM Assigned WHERE empid = Employee.empid and projid = Project.projid
    )
)
Run Code Online (Sandbox Code Playgroud)

它应该返回分配给每个项目的所有员工的姓名,并且它确实有效,但是我对它如何/为什么正确工作感到困惑。

架构是:

员工(empID INT,empName VARCHAR(100),工作VARCHAR(100),部门ID INT,工资INT);
已分配(empID INT,projID INT,角色 VARCHAR(100));
项目(projID INT,标题 VARCHAR(100),预算 INT,资金 INT);

我是 SQL 新手,所以详细/简单的解释将不胜感激。

sge*_*des 5

当我需要尝试了解正在发生的事情时,我会寻找最内部的查询并向外进行工作。对于您的情况,让我们从以下开始:

\n\n
SELECT empid, projid \nFROM Assigned \nWHERE empid = Employee.empid and projid = Project.projid\n
Run Code Online (Sandbox Code Playgroud)\n\n

这与分配表中的所有记录相匹配,其中 empid 和 projid 位于前面的表中(因此是 Employee.empid 和 Project.projid)。

\n\n

假设“项目”表中有 5 个项目,并且将 Employee1 分配给每个项目。这将返回 5 条记录。另假设 Employee2 被分配给其中 1 个项目,从而返回 1 条记录。

\n\n

接下来看:

\n\n
SELECT projid FROM Project WHERE not exists (\n        ...\n    )\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,这表示对于在上一个查询中找到的记录(Employee1 有 5 个项目,Employee2 有 1 个项目),从 Project 表中选择任何与上一个查询不存在任何匹配(不存在)的 projid。换句话说,Employee1 不会从此查询返回任何项目,但 Employee2 将返回 4 个项目。

\n\n

最后,看看

\n\n
 SELECT empname FROM Employee WHERE not exists (\n        ...\n    )\n
Run Code Online (Sandbox Code Playgroud)\n\n

与第二个查询一样,对于上一个查询中找到的任何记录(没有记录将这些员工与所有项目(如 Employee1)相匹配,如果员工未分配到每个项目(如 Employee2),则选择一些记录),选择任何员工来自 Employee 表,其中没有任何匹配项(同样,不存在)。换句话说,Employee1 将返回,因为前一个查询未返回任何项目,而 Employee2 将不会返回,因为前一个查询返回了 1 个或多个项目。

\n\n

希望这可以帮助。以下是有关 EXISTS 的一些附加信息:

\n\n

http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html

\n\n

在那篇文章中:

\n\n
\n

所有城市都有什么类型的商店?

\n
\n\n
SELECT DISTINCT store_type FROM stores s1   WHERE NOT EXISTS (\n    SELECT * FROM cities WHERE NOT EXISTS (\n      SELECT * FROM cities_stores\n       WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

最后一个示例是双重嵌套的 NOT EXISTS 查询。也就是说,它在 NOT EXISTS 子句中包含 NOT EXISTS 子句。正式地,它回答\n问题 \xe2\x80\x9c 是否存在一个城市,其商店不在 Stores\xe2\x80\x9d 中?\n 但更容易说嵌套的 NOT EXISTS 回答了问题\n \xe2\x80\x9cis x 对于所有 y 都为 TRUE?\xe2\x80\x9d

\n
\n\n

祝你好运。

\n