SQL中的NOT EXISTS子句

use*_*410 1 sql not-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 
    ) 
);
Run Code Online (Sandbox Code Playgroud)

数据库结构是:

带有列的表项目:

Pname,Pnumber,Plocation和dnum

表works_on与列:

ESSN,PNO和HOURS

表员工列:

Fname,minit,Lname,SSN,Bdate,地址,性别,工资,superssn和dno

如果有人能用简单的词语解释这个查询是如何执行的,那将非常有用.

Key*_*erS 9

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

因此,通过暗示NOT 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 ) );
Run Code Online (Sandbox Code Playgroud)

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

SELECT PNO 
    FROM WORKS_ON
    WHERE ESSN=E.SSN
Run Code Online (Sandbox Code Playgroud)

如果这返回零行(因为我们已经说过NOT EXISTS),那么它将运行下一个查询,它将是:

SELECT PNUMBER
    FROM PROJECT
Run Code Online (Sandbox Code Playgroud)

同样,这必须返回零行,如果是,则它将运行最后一个查询,这是第一个查询.

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E
Run Code Online (Sandbox Code Playgroud)

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

有关EXISTS条件的更多信息,请参见此处