持续创作,加速成长!这是我参与「掘金日新计划 · 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存在于内部子查询中,这就是相关子查询。执行步骤即:
- 先查询外部的表,从结果中取一条数据传入内部。
- 内部根据结果查询满足条件的结果返回。
- 再从外部的结果中取一条数据传入内部进行查询。
循环直到外部结果查询完成。
方式二
在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之外,其他位置都可以声明子查询。
今天先学习到这里,明天继续。