目录
概述
- 含义:出现在其他语句(可以是增删改查等任何语句)中的select语句,称为子查询或内查询
- 如果是套嵌在查询语句中的子查询,那么外部的查询语句叫做主查询或外查询
分类(以套嵌查询语句为例)
- 按子查询出现的位置进行分类:
select
后面:仅仅只支持标量子查询from
后面:支持表子查询where
或having
后面(重点):支持标量子查询、列子查询,也支持行子查询,但是用的较少exists
后面(相关子查询):支持表子查询
- 按结果集的行列数(或功能)不同进行分类:
- 标量子查询(结果只有一列一行)也叫做单行子查询
- 列子查询(结果集一列多行)也叫多行子查询
- 行自查询(结果有一行多列或多行多列)
- 表子查询(结果集一般为多行多列)
where或having后面的子查询
特点
- 子查询放在小括号内
- 子查询一般放在条件右侧
- 标量子查询,一般搭配着单行操作符(
>、<、>=、<=、=、<>
)使用 - 列子查询,一般搭配着多行操作符(
IN、ANY/SOME、ALL
)使用 - 子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果
标量子查询
- 谁都工资比Abel高
- 先查询Abel的工资
- 查询工资大于Abel的员工
- 先查询Abel的工资
- 返回job_id与141号员工相同,salary比143号员工多的员工姓名、job_id和工资(多个子查询)
- 返回公司工资最少的员工的last_name,job_id和salary(用上分组函数)
- 查询最低工资大于50号部门最低工资的部门id和其最低工资(子查询跟在
having
关键字后面)
- 非法使用标量子查询的情况:子查询的结果不是一行一列,都算为非法使用标量子查询
列子查询(多行子查询)
- 子查询返回的结果是多行
- 需要搭配使用多行比较操作符
IN/NOT IN
:等于列表中的任意一个ANY/SOME
:和子查询返回的某一个值比较ALL
:和子查询返回的所有值比较
- 返回location_id是1400或1700的部门中的所有员工姓名
- 返回其他工种中的比job_id为’IT_PROG’部门任一工资低的员工的工号、姓名、job_id以及salary
行子查询(多列子查询)(不常用)
-
查询员工编号最小并且工资最高的员工信息
- 使用列子查询(多行子查询)
- 使用行子查询(==必须多个条件都为等号才能使用列子查询)
- 使用列子查询(多行子查询)
放在select后面的子查询
特点
- 仅仅支持标量子查询
- 由于大部分都可以用其他的查询方式来代替,因此不常用
案例
- 查询每个部门的员工个数
- 也可以使用外连接来实现(分组函数会忽略null值)
- 也可以使用外连接来实现(分组函数会忽略null值)
- 查询员工号=102的部门名(完全不需要用列子查询来实现,红框内就可以实现其功能)
放在from后面的子查询
特点
- 将子查询的结果充当一张表,要求必须起别名
案例
- 查询每个部门的平均工资的工资等级
放在exists后面的子查询(相关子查询)(不常用)
语法和特点
- 语法:
exists (完整的查询语句)
- 返回:括号中的查询语句是否为空(相当于布尔值,1为true,0为false)
- 1:括号中的查询语句有值(不为空)
- 0:括号中的查询语句没有值(为空)
- 一般来说,该查询语句都可以用之前学过的语句代替,因此用到的也较少
案例
- 查询有员工的部门名