一、什么是子查询
子查询指一个查询语句嵌套在另一个查询语句内部的查询
SQL 中子查询的使用大大增强了 SELECT 查询的能力,因为很多时候查询需要从结果集中获取数据,或者需要从同一个表中先计算得出一个数据结果,然后与这个数据结果(可能是某个标量,也可能是某个集合)进行比较,这是子查询的核心!
二、为什么要用子查询
先看一个实际需求: 查询谁的工资比 Abel 的高
有三种解答方式:
#方式1:分开查询,先查询Abel的工资,在让其工资与别的员工比较 SELECT salary FROM employees WHERE last_name = 'Abel'; SELECT last_name,salary FROM employees WHERE salary > 11000; #这里的11000是经过上面的查询后得到的 #方式2:使用自连接 SELECT e2.last_name,e2.salary FROM employees e1,employees e2 WHERE e2.`salary` > e1.`salary` AND e1.last_name = 'Abel'; #方式3:子查询 SELECT last_name,salary FROM employees WHERE salary > ( SELECT salary FROM employees WHERE last_name = 'Abel' );
很显然,第一种方式太过于繁琐,抛开查询效率,最后两种方式比较简洁,我们应该以最后两种方式为主。
三、子查询的基本使用
语法结构: select 查询列表 from 表 where (查询语句);
子查询在主查询之前一次执行完成
子查询的结果被主查询使用
注意事项
子查询要包含在括号内
将子查询放在比较条件的右侧
单行操作符对应单行子查询,多行操作符对应多行子查询
四、子查询的分类
1、单行子查询
返回的结果是一条记录
操作符:
操作符 含义
= 等于
> 大于
>= 不小于
< 小于
<= 不大于
<> 不等于
2、多行子查询
返回的结果是多条记录
操作符:
操作符 含义
IN 等于列表中的任意一个
ANY 需要和单行比较操作符一起使用,和子查询返回的某一个值比较
ALL 需要和单行比较操作符一起使用,和子查询返回的所有值比较
SOME 实际上是ANY的别名,作用相同,一般常使用ANY
注意在例题中体会 ANY 和 ALL 的区别
3、相关子查询
子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部,这种嵌套的执行方式就称为相关子查询
相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询
4、非相关子查询
子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行,那么这样的子查询叫做不相关子查询,因为跟相关子查询相反,所以就详解相关子查询。
例题详解
1、单行子查询例题
例题1
查询工资大于149号员工工资的员工的信息
SELECT * FROM employees WHERE salary > ( SELECT salary FROM employees WHERE employee_id = 149 ); #解题思路:先写内查询,查询出149号员工的工资,最后再写外查询,找到满足条件的员工
例题2
返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
SELECT last_name,job_id,salary FROM employees WHERE job_id = ( SELECT job_id FROM employees WHERE employee_id = 141 ) AND salary > ( SELECT salary FROM employees WHERE employee_id = 143 ); #解题思路:跟例题1一样,只是多了一个查询条件