3

我一直在查询,我真的无法思考执行是如何发生的,任何帮助将不胜感激:

该查询旨在查找从事所有项目的员工的详细信息。

查询是:

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E
WHERE NOT EXISTS
(
    SELECT PNUMBER
    FROM PROJECT
    WHERE PNUMBER NOT EXISTS 
    (
        SELECT PNO 
        FROM WORKS_ON
        WHERE ESSN=E.SSN 
    ) 
);

数据库结构是:

带有列的表项目:

Pname、Pnumber、位置和 dnum

带有列的表works_on:

ESSN、PNO 和 HOURS

表 Employee 与列:

Fname,minit,Lname,SSN,Bdate,address,sex,salary,superssn 和 dno

如果有人能用简单的话解释这个查询是如何执行的,那将非常有帮助。

4

3 回答 3

10

如果子查询返回至少一行,则认为 SQL EXISTS 条件“满足”。

因此,通过暗示不存在,我们希望子查询返回零行,所以有了这些知识,让我们看看您的查询

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E
WHERE NOT EXISTS (SELECT PNUMBER
FROM PROJECT
WHERE PNUMBER NOT EXISTS (SELECT PNO 
FROM WORKS_ON
WHERE ESSN=E.SSN ) );

有两个嵌套的 NOT EXISTS 语句,SQL 必须以相反的顺序运行它们,因为一个依赖于另一个。第一个将被查询的是这个(最后一个):

SELECT PNO 
    FROM WORKS_ON
    WHERE ESSN=E.SSN

如果这返回零行(因为我们说不存在),那么它将运行下一个查询,这将是:

SELECT PNUMBER
    FROM PROJECT

同样,这必须返回零行,如果返回,那么它将运行最终查询,即第一个查询。

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E

本质上,每个“NOT EXIST”子查询都必须返回零行才能运行前面的查询,否则您最终将得到 0 行(无结果)。

有关 EXISTS 条件的更多信息,请单击此处

于 2013-02-25T07:42:27.907 回答
1

我知道这是一个老问题,但我很感兴趣,所以我花了一些时间来解决这个问题,让努力白白浪费了。

首先,我不知道 inner 的语法,<column name> NOT EXISTS <subquery>但它似乎等同于<column name> NOT IN <subquery>. 正是这个概念使查询对我来说更全面,因为它更清楚地将内部查询链接到PROJECT
所以我从

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E
WHERE NOT EXISTS
(
    SELECT PNUMBER
    FROM PROJECT
    WHERE PNUMBER NOT IN
    (
        SELECT PNO
        FROM WORKS_ON
        WHERE ESSN=E.SSN
    )
);

步骤分解:

  • 内部查询仅列出您的员工从事的所有项目编号。

            SELECT PNO
            FROM WORKS_ON
            WHERE ESSN=E.SSN
    
  • 中间查询采用补码。结果是您的员工未处理的所有项目编号。

        SELECT PNUMBER
        FROM PROJECT
        WHERE PNUMBER NOT IN
        (
            -- projects that the employee works on
        )
    
  • 如果存在员工不参与的项目,那么他不会参与所有项目,因此他不应该被包括在结果中。

    SELECT E.LNAME, E.FNAME
    FROM EMPLOYEE E
    WHERE NOT EXISTS
    (
        -- projects that the employee does not work on
    )
    
于 2017-05-02T13:44:48.373 回答
0

对于这个问题, keyszers的回答绰绰有余。不过我想再补充几点

SQL 查询的执行从内部查询开始。因此,在您的查询中,where 子句首先执行

PNUMBER 不存在(从 WORKS_ON WHERE ESSN=E.SSN 中选择 PNO)

根据上述查询的结果,下面的另一个查询将运行。

WHERE NOT EXISTS (
    SELECT PNUMBER
    FROM PROJECT
    WHERE PNUMBER NOT EXISTS (**Resultset**)

总结一下我的观点 - 您需要根据子查询中的结果集调试您的查询。

于 2018-06-19T07:35:38.623 回答