第16节--子查询
子查询
含义:嵌套在其他语句内部的select语句为子查询或内查询,外边的语句可以是instr,update,delete,select等,一般select作为外部语句较多。
外面如果为select,则此语句为外查询或主查询。
分类
1. 按出现的位置
select 后面(仅支持标量子查询)
from后面(表子查询)
where或having后面,后可跟标量子查询,列子查询,行子查询
exist后面,可跟 相关子查询,标量子查询,列子查询,行子查询,表子查询
2. 按结果集的行列
标量子查询(单行子查询):结果为一行一列
列子查询(多行子查询):结果集为多行一列
行子查询(结果集为多行多列)
表子查询(结果集为多行多列)
#1.where 或 having后面
1. 标量子查询(单行子查询)
2. 列子查询(多行子查询)
3. 行子查询(多行多列)
特点: ① 子查询放在小括号内
② 子查询一般放在条件的右侧
③ 标量子查询,一般搭配着单行操作符使用>, <, >=, <= , =, <>
④列子查询,,一般搭配着多行操作符使用 in, any, some, all
说明:子查询的执行优先于主查询,主查询的条件用到了子查询的结果。
标量子查询
#where后
案例:1. 返回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);
案例2. 查询和Zloktkey相同的部门的员工姓名,工资
select last_name,salary from employees where department_id=(select department_id from employees where last_name='Zlotkey');
案例3. 谁的工资比Abel的工资高(标量子查询) select last_name from employees where salary>(select salary from employees where last_name='Abel');
#having 子句
案例1:查询最低工资大于50号部门最低工资的部门id和其最低工资 步骤:① select min(salary) from employees where department_id=50; ②select min(salary), department_id from employees group by department_id having min(salary)>(select min(salary) from employees where department_id=50);
列子查询
操作符
操作符 | 含义 |
in/not in | 等于列表中的任意一个 |
any/some | 和子查询返回的某一个值比较 |
all | 和子查询返回的所有值比较 |
案例1. 返回location_id 是1400或1700的部门中的所有员工姓名
步骤:① select department_id from employees where location_id in(1400,1700); ②select last_name from employees where department_id in (select distinct department_id from locations where location_id in(1400,1700));
案例2:返回其他部门中比job_id为‘IT_PROG’部门任一工资低的员工的员工号,姓名,job_id以及salary 步骤:① select salary from employees where job_id='IT_PROG'; ② select employee_id,last_name,job_id,salary from employees where salary < any(select salary from employees where job_id='IT_PROG') and job_id<>'IT_PROG';
行子查询(结果集为一行多列或多行多列)
案例 :查询员工编号最小且工资最高的员工员工信息 select * from employees where employee _id=(select min(employee_id) from employees) and salary=(select max(salary) from employees);
select 后面 仅仅支持标量
查询每个部门的员工个数 select d.*, (select count(*) from employees e where e.department_id=d.department_id) 员工个数 from departments d;
from后面
将子查询结果同意当一张表,要求必须起别名
案例:查询每个部门的平均工资的工资等级 步骤:①查询每个部门的平均工资 select avg(salary), department_id from employees group by department_id ② select a.*,job_grades from (select avg(salary) avg, department_id from employees group by department_id) a inner join jobs j on a.avg between lowest_sal and higest_sal;
exists 后面(相关子查询)
语法:exist(完整的查询语句)
结果:1或0(查询结果存在,结果就为1,不存在结果就为0)
案例1:查询有员工的部门名
select department_name from departments d where exists(select * from employees e where d.department_id=e.department_id);
或 用‘in’
select department_name from departments d where d.department_id in (select department_id from employees);
案例2:查询没有女朋友的男神信息 #in
#in select bo.* from boys bo where bo.id not in(select boyfriend_id from beauty) ; #exist select bo.* from boys bo where not exists(select boyfriend_id from beauty b where bo.id=b.boyfriend_id)
Jasminelee