Mysql 为什么在WHERE EXISTS构造中使用简单谓词时,此SQL代码不能工作?

Mysql 为什么在WHERE EXISTS构造中使用简单谓词时,此SQL代码不能工作?,mysql,sql,Mysql,Sql,我正在处理一个示例数据库,以作为类的一部分学习SQL。其中一项任务是列出使用EXISTS的经理的员工姓名。我已经完成了作业,所以可以在这里得到答案 我最初使用的是: SELECT `FIRSTNAME` , `MIDINIT` , `LASTNAME` FROM `emp` WHERE EXISTS (SELECT * FROM `emp` WHERE `JOB`='MANAGER') 然而,这根本不起作用 它一直在emp表中显示所有员工的姓名,而不是JOB='M

我正在处理一个示例数据库,以作为类的一部分学习SQL。其中一项任务是列出使用EXISTS的经理的员工姓名。我已经完成了作业,所以可以在这里得到答案

我最初使用的是:

SELECT `FIRSTNAME`
     , `MIDINIT`
     , `LASTNAME` 
  FROM `emp` 
 WHERE EXISTS (SELECT * FROM `emp` WHERE `JOB`='MANAGER')
然而,这根本不起作用

它一直在emp表中显示所有员工的姓名,而不是JOB='MANAGER'所在的7名员工

这是奇怪的部分

当我刚跑的时候

(SELECT * FROM `emp` WHERE `JOB`='MANAGER')
它只显示员工是经理的7行。

那么,为什么它不能用作WHERE-EXISTS谓词呢

为了让它工作,我必须这样做: 从存在的emp中选择FIRSTNAME、MIDINIT、LASTNAME从emp.EMPNO=dept.MGRNUMBER的部门中选择*
我必须将emp表中的EMPNO与dept表中的MGR编号进行比较。我不明白为什么我必须转到另一个表来比较值。

此查询应该可以解决您的问题:

您不需要访问其他表

EXISTS操作是一个测试子查询中是否存在某些内容的操作符。如果存在匹配项,则返回TRUE

因此,如果您只想使用emp表,那么必须使用EMPNO连接子查询中的查询

在我的示例中,我通过在主查询中将表emp声明为emp1,在子查询中将表emp2声明为emp2来实现这一点。这使得在子查询中搜索是否存在EMPNO成为可能

SELECT 
     FIRSTNAME,
     MIDINIT,
     LASTNAME 
FROM emp emp1 
WHERE EXISTS ( SELECT * 
               FROM emp emp2 
               WHERE emp1.EMPNO = emp2.EMPNO 
                 AND emp2.JOB='MANAGER' );

此查询将解决您的问题:

您不需要访问其他表

EXISTS操作是一个测试子查询中是否存在某些内容的操作符。如果存在匹配项,则返回TRUE

因此,如果您只想使用emp表,那么必须使用EMPNO连接子查询中的查询

在我的示例中,我通过在主查询中将表emp声明为emp1,在子查询中将表emp2声明为emp2来实现这一点。这使得在子查询中搜索是否存在EMPNO成为可能

SELECT 
     FIRSTNAME,
     MIDINIT,
     LASTNAME 
FROM emp emp1 
WHERE EXISTS ( SELECT * 
               FROM emp emp2 
               WHERE emp1.EMPNO = emp2.EMPNO 
                 AND emp2.JOB='MANAGER' );
您的原始查询:

SELECT `FIRSTNAME`
     , `MIDINIT`
     , `LASTNAME` 
  FROM `emp` 
 WHERE EXISTS (SELECT * FROM `emp` WHERE `JOB`='MANAGER')
…是这样工作的。对于表中找到的每一行,它检查WHERE子句,该子句查找是否存在Job='MANAGER'的任何行。它找到了一些,因此它包含了行。然后它获取下一行并重复通过的相同检查,因此它包含下一行。它对每一行重复,因此包括表中的所有行

@GenYMaverick的答案是使用EXISTS的一种方法,但我不会在生产中使用它。我会使用您提出的查询,因为它是最简单、最自然、可能也是最有效的方法。我还希望查询优化程序能够将@GenYMaverick的查询简化为您的查询;它们在逻辑上是相同的。

您的原始查询:

SELECT `FIRSTNAME`
     , `MIDINIT`
     , `LASTNAME` 
  FROM `emp` 
 WHERE EXISTS (SELECT * FROM `emp` WHERE `JOB`='MANAGER')
…是这样工作的。对于表中找到的每一行,它检查WHERE子句,该子句查找是否存在Job='MANAGER'的任何行。它找到了一些,因此它包含了行。然后它获取下一行并重复通过的相同检查,因此它包含下一行。它对每一行重复,因此包括表中的所有行


@GenYMaverick的答案是使用EXISTS的一种方法,但我不会在生产中使用它。我会使用您提出的查询,因为它是最简单、最自然、可能也是最有效的方法。我还希望查询优化程序能够将@GenYMaverick的查询简化为您的查询;它们在逻辑上是相同的。

EXISTS需要一个相关的子查询来解释。现在,如果存在JOB='MANAGER'的行,您将获取所有行,如果不存在这样的行,则将不获取任何行。是的,这正是发生的情况——我获取了所有行。我认为它将从子查询收集所有信息,然后在子查询上运行主查询。它不是这样工作的吗?它需要一个相关的子查询来解释。现在,如果存在JOB='MANAGER'的行,您将获取所有行,如果不存在这样的行,则将不获取任何行。是的,这正是发生的情况——我获取了所有行。我认为它将从子查询收集所有信息,然后在子查询上运行主查询。它不是那样工作的吗?我对SQL还不够了解,所以我不理解这里的emp1或emp2。我想这会使新表成为原始表的副本?@mdign002我不理解emp1或emp2这些是别名。临时,根据此查询,表复制的名称用于区分每个表达式中使用的表列。在emp1.EMPNO=emp2.EMPNOI的情况下需要。我在SQL中很新,所以我不理解这里的emp1或emp2。我想这会使新表成为原始表的副本?@mdign002我不理解emp1或emp2这些是别名。临时,根据此查询,表复制的名称用于区分每个表达式中使用的表列。需要 在emp1.EMPNO=emp2.EMPNO的条件下