MySql 工作台中的相关子查询

问题描述

这是我在互联网上查找“相关子查询”时最常见的示例:

 SELECT employee_number,name
   FROM employees emp
   WHERE salary > (
     SELECT AVG(salary)
       FROM employees
       WHERE department = emp.department)

但我的问题是:在这个语法中,(以及其他类似的相关子查询)这是子查询最后一行的“函数” -> WHERE department = emp.department) ?

我的意思是,当执行这一行时,MysqL 会做什么?我不清楚这种语法背后的逻辑。

我试图只执行子查询,以便查看/理解给出的输出是什么,但它给了我错误。如何理解内部查询输出

我的目标是清楚地理解这个语法背后的逻辑,以便我能够理解何时使用它。如果它太复杂,是否有某种规则可以理解何时使用它?在哪个问题前面你说:“好吧,我必须使用相关子查询(用我的例子的语法)”?

解决方法

首先,让我们重写查询以对所有表使用别名并限定所有列。事情会变得更加清晰:

SELECT e1.employee_number,e1.name
       FROM employees e1
            WHERE e1.salary > (SELECT avg(e2.salary)
                                      FROM employees e2
                                      WHERE e2.department = e1.department);

(我建议你养成这样的习惯。要么使用别名并限定所有内容,要么什么都不做。两者的混合只是一团糟。)

现在回答您的问题:

要使子查询相关,它需要以某种方式“连接”到外部查询,否则就不相关。这就是子查询中的 WHERE 子句所做的。

如您所见,我们在整个查询中得到了 employees 的两个实例,别名为 e1e2。 (如果你有一个使用两个不同表的例子,它可能更容易理解......)

对于 e1 的每一行,子查询从 salary 获取平均 e2,其中 e2 的行与当前处理的行具有相同的 department来自e2。 (至少这是逻辑上发生的事情——物理上执行的内容可能会在这里和那里采取一些捷径,但这对于理解含义并不重要查询。)然后将共享 salary 的平均值 departmentsalary 行的 e1> 进行比较。

子查询不能单独执行,因为它是相关的。因此,如果您将它从整个查询的上下文中取出,就没有可比较的 department,因为不再有其他实例 e1。因此它失败了。

,

查询描述的是结果集,而不是执行计划——优化器会计算出来。

您的查询是相关子查询。第一件事是限定所有列引用,以便真正清楚哪些列是哪些:

SELECT e.employee_number,e.name
FROM employees e
WHERE e.salary > (SELECT AVG(e2.salary)
                  FROM employees e2
                  WHERE e2.department = e.department
------------------------^ correlation clause
                 );

这是在做什么?从概念上讲,引擎循环遍历 employees 表的每一行。对于每一行,它然后将薪水与同一部门中所有薪水的平均值进行比较——这就是相关性子句的作用。

这描述了产生的结果集。实际的执行计划可能与上面描述的有所不同。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...