我很难理解NOT EXISTS
和子查询的组合是如何工作的。
我理解通过添加NOT EXISTS
,查询将返回子查询不会返回的所有行。在以下情况下我们使用它时,我不明白它是如何工作的。
+-------------+--------+
| id_employee | salary |
+-------------+--------+
| E001 | 1000 |
| E002 | 1001 |
| E003 | 999 |
| E004 | 1001 |
+-------------+--------+
并尝试以下查询:
SELECT E.id_employee, E.salary
FROM Employees E
WHERE NOT EXISTS (
SELECT F.id_employee
FROM Employees F
WHERE F.salary > E.salary
);
返回:
+-------------+--------+
| id_employee | salary |
+-------------+--------+
| E002 | 1001 |
| E004 | 1001 |
+-------------+--------+
好吧,我真的无法理解F.salary > E.salary
比较是如何工作的,因为如果它逐行比较两个表(它们是相同的),那么它们是否有意义我要退回任何一行。
你能否给我一些关于它是如何工作的暗示?
答案 0 :(得分:1)
NOT EXISTS
通常与Correlated Subquery一起使用,即Outer和Inner查询之间存在关系(如果没有“table not found”错误,则无法自行运行子查询代码)。你的例子是相关的,但是很奇怪。
逻辑上它的处理方式如下:
对于employee表中的每一行,运行以下查询:
SELECT F.id_employee
FROM Employees F
WHERE F.salary > <salary of the current row>
如果此查询未返回任何行(即,没有薪水大于当前行的行),则NOT EXISTS
计算结果为true并从employee表中返回此行。
实际上,此查询返回薪水最低的行。
相关EXISTS
与JOIN
非常相似,而NOT EXISTS
是一种反JOIN,只返回那些无法连接的行。这是常见用法,查找第二个表中不存在的值的行,例如查找具有无效/不存在的部门编号的员工
SELECT *
FROM Employees E
WHERE NOT EXISTS (
SELECT *
FROM Departments D
WHERE E.department_number = D.department_number
);
答案 1 :(得分:0)
由于您在子查询中没有指定其他条件而不是:
F.salary > E.salary
你从E
获得任何一行,其中F
中没有其他条目的薪水高于它。由于E002
和E004
的薪水均为1001
,而其他任何人的工资都不超过1001
,E002
和E004
归还。
如果您将WHERE
更改为:
F.salary >= E.salary
由于每个人的薪水都低于或等于另一名员工的薪水,您将无法获得任何记录。
答案 2 :(得分:0)
好的,每行都会计算WHERE
子句。 WHERE
子句将仅返回谓词求值为TRUE
的行。你的谓词是
NOT EXISTS (
SELECT F.id_employee
FROM Employees F
WHERE F.salary > E.salary
);
因此,结果集将仅包含将此谓词计算为TRUE
的行。对于工资为1000的第1行,存在工资较大的行,因此对于此行,谓词为FALSE
,并从结果集中删除。第二行薪水是1001,并且没有其他行的薪水更高,因此对于此行,谓词的计算结果为TRUE
,此行将位于结果集中。