MySQL学习-相关子查询(一)

313 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

前言

上篇我们学习了MySQL子查询中的多行子查询。有兴趣的小伙伴可以阅读(# MySQL学习-多行子查询)。
下面继续学习MySQL子查询中的相关子查询。

学习子查询开头,我们知道子查询有2种分类方式:

方式一: 单行子查询与多行子查询。
方式二: 相关子查询与不相关子查询。

其中方式二是按照子查询是否被执行多次划分的。不相关子查询的数据结果只执行一次,而相关子查询需要执行多次。

相关子查询

相关子查询的执行流程

如果子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表,并进行了条件关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称为相关子查询。

相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。

举例一

查询员工中工资大于本公司平均工资的员工的name, salary和department_id。
这是学习单行子查询的例子,这是查询本公司的平均工资,是一个确定的值,只执行一次。所以是不相关子查询。

SELECT name, salary, department_id
FROM employees
WHERE salary > (
                SELECT AVG(salary)
                FROM employees
                );

举例二

查询员工中工资大于本部门平均工资的员工的name, salary和department_id。

方式一

使用相关子查询。这里查询的是本部门,每个员工对应的是不同的部门,子查询的结果需要根据主查询的结果执行多次。这是相关子查询。

SELECT name, salary, department_id
FROM employees e1
WHERE salary > (
                SELECT AVG(salary)
                FROM employees e2
                WHERE department_id = e1.'department_id'
                );

这里外部的表e1存在于内部子查询中,这就是相关子查询。执行步骤即:

  1. 先查询外部的表,从结果中取一条数据传入内部。
  2. 内部根据结果查询满足条件的结果返回。
  3. 再从外部的结果中取一条数据传入内部进行查询。

循环直到外部结果查询完成。

方式二

在FROM中声明子查询。查询每个部门的平均工资当作新表,再进行查询。

SELECT e.name, e.salary, e.department_id
FROM employees e, (
                SELECT department_id, AVG(salary) avg_sal
                FROM employees
                GROUP BY department_id
                ) t_dept_avg_sal
WHERE e.department_id = t_dept_avg_sal.department_id
AND e.salary > t_dept_avg_sal.avg_sal;

通过FORM声明子查询的方式,也可以查出结果。

举例三

查询员工的id,salary,按照department_name排序。
排序使用ORDER BY,这里在ORDER BY中使用子查询。

SELECT employee_id, salary
FROM employees e
ORDER BY (
           SELECT department_name
           FROM departments d
           WHERE d.'department_id' = e.'department_id'
        ) ASC;

从上面的例子中可以看到,我们可以在FROM和ORDER BY中使用子查询。

结论: 在SELECT中,除了GROUP BY和LIMIT之外,其他位置都可以声明子查询。

今天先学习到这里,明天继续。