MySQL子查询

含义:

出现在其他语句中的select语句,称为子查询或内查询;外部的查询语句,称为主查询或外查询。

分类:

按子查询出现的位置:
select后:仅支持标量子查询
from后:支持表子查询
where或having后(重点)::支持标量子查()、列子查询()、行子查询(使用较少)
exists后(相关子查询):表子查询
按结果集的行列数不同:
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)
表子查询(结果集一般为多行多列)

一、where和having后面:

1、标量子查询(单行子查询):
#案例1:谁的工资比Abel高?
① 查询Abel的工资:

select salary
from employees where lastName = 'Abel';

② 查询员工的信息,满足salary > ①的结果:

select * 
from employees
where salary > (
	select salary
	from employees 
	where lastName = 'Abel'
);

#案例2:返回jobId与141号员工相同,salary比143号员工多的员工姓名、jobId和工资:
① 查询141号员工的jobId;

select jobId
from employees
where employeeId = '141';

② 查询143号员工的salary:

select salary
from employees
where employeeId = '143';

③ 查询员工姓名、jobId和工资,要求jobId = ①,salary > ②的结果:

select lastName, jobId, salary
from employees
where jobId = (
	select jobId
	from employees
	where employeeId = '141'
) and salary > (
	select salary
	from employees
	where employeeId = '143'
);

#案例3:查询公司工资最少的员工的lastName,jobId和salary:
① 查询公司的最少工资:

select min(salary)
from employees;

② 查询工资满足①的员工的lastName,jobId和salary:

select lastName,jobId,salary
from employees
where salary = (
	select min(salary)
	from employees
);

#案例4:查询最低工资大于50号部门最低工资的部门ID和其最低工资:
① 查询50号部门的最低工资:

select min(salary)
from employees
where departmentId = '50';

② 查询每个部门的最低工资:

select min(salary), departmentId
from employees
group by departmentId;

③ 筛选②的结果,要求min(salary) > ①:

select min(salary), departmentId
from employees
group by departmentId
having min(salary) > (
	select min(salary)
	from employees
	where departmentId = 50
);

2、列子查询(多行子查询):
#案例1:查询locationId是1400或1700的部门中的所有员工姓名
① 查询locationId是1400或1700的部门编号

select departmentId
from departments
where locationId in(14001700);

② 查询员工姓名,要求部门号是①中的某一个

select lastName
from employees
where departmentId in (
	select distinct departmentId
	from departments
	where locationId in(14001700)
);

#以上语句等价于:
select lastName
from employees
where departmentId = any (
	select distinct departmentId
	from departments
	where locationId in(14001700)
);

#案例2:查询其他工种中比jobId为‘IT_PROG’工种任一工资低的员工的工号、姓名、jobId和salary
① 查询jobId为‘IT_PROG’部门的任一工资;

select distinct salary
from employees
where jobId = 'IT_PROG'

② 查询员工的工号、姓名、jobId和salary,要求salary<①中的任一一个

select employeeId, lastName, jobId, salary
from employees
where salary < any(
	select distinct salary
	from employees
	where jobId = 'IT_PROG'
) and jobId <> 'IT_PROG';

# 以上语句等价于:
select employeeId, lastName, jobId, salary
from employees
where salary < (
	select max(salary)
	from employees
	where jobId = 'IT_PROG'
) and jobId <> 'IT_PROG';

#案例3:查询其他工种中比jobId为‘IT_PROG’工种所有工资低的员工的工号、姓名、jobId和salary

select employeeId, lastName, jobId, salary
from employees
where salary < all(
	select distinct salary
	from employees
	where jobId = 'IT_PROG'
) and jobId <> 'IT_PROG';

# 以上语句等价于:
select employeeId, lastName, jobId, salary
from employees
where salary < (
	select min(salary)
	from employees
	where jobId = 'IT_PROG'
) and jobId <> 'IT_PROG';

3、行子查询(结果集一行多列或多行多列):
#案例:查询员工编号最小并且工资最高的员工信息:
普通查询:
① 查询最小的员工编号:

select min(employeeId)
from employees

② 查询最高的工资:

select max(salary)
from employees

③ 查询员工信息:

select *
fromm employees
where employeeId = (
	select min(employeeId)
	from employees
) and salary = (
	select max(salary)
	from employees
);

行子查询:

select *
fromm employees
where (employeeId, salary) = (
	select min(employeeId), max(salary)
	from employees
);

特点:
① 子查询放在小括号内;
② 子查询一般放在条件的右侧;
③ 标量子查询一般搭配单行操作符(>、<、>=、<=、=、<>)使用;列子查询一般搭配多行操作符(in、any/some、all)使用;
④ 子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果。

二、select后面:

仅支持标量子查询。
#案例1:查询每个部门的员工个数

select d.*, (
	select count(*)
	from employees
	where e.departmentId = d.departmentId
)
from departments d;

#案例2:查询员工号=102的部门名

select (
	select departmentName, e.departmentId
	from departments d
	inner join employees e
	on d.departmentId = e.departmentId
	where e.employeeId = 102
) 部门名
三、from后面:

将子查询结果充当一张表,要求必须起别名。
#案例:查询每个部门的平均工资的工资等级
① 查询每个部门的平均工资:

select AVG(salary) ag, departmentId
from employees
group by departmentId

② 连接①的结果集和jobGrades表,筛选条件:平均工资 between lowestSalary and highestSalary

select agDep.*, g.gradeLevel
from (select AVG(salary),departmentId
from employees
group by departmentId) agDep
inner join jobGrades g
on avgDep.ag between lowestSalary and highestSalary
四、exists后面(相关子查询):

exists (完整的查询语句)
结果:1或0。

select exists(
	select employeeId from employees
);

#案例:查询有员工的部门名:

select departmentName 
from departments d
where exists (
	select * 
	from employees e
	where d.departmentId = e.departmentId
);
// 以上查询语句等价于:
select departmentName 
from departments d
where departmentId in (
	select * 
	from employees
);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值