目录
一、子查询
1.1 什么是子查询
一般一个查询,就出现一次select 语句,但如果又出现select 语句,此时就称后者为‘子查询’,前者为‘主查询’
1.2 子查询的语法
select 字段或者表达式或者(子查询1) [as 别名] from 表名或者(子查询2) where 字段或者表达式或者(子查询3)
通常每个位置的子查询,应该符合该位置的数据需求
- 子查询1 应该是一个‘数据结果’
- 子查询2 可以是‘任意结果’
- 子查询3 可以是一个数据或者一列数据
1.3 子查询的分类
1.表子查询:子查询结果为‘多行多列’,通常可以当做‘表’放在 from 后面使用
#查询工资最高的三个员工的信息,包含所在部门名称
select top3.*, d.dnamefrom (select * from emp order by sal desc limit 3) as top3 inner join dept d on top3.depton = d.depton;
2.行子查询:子查询结果为‘一行多列’,通常可以当做‘行’来使用,放在‘行比较语法’
select * from emp where (sal,deptno) = (select sal,deptno from emp order by sal desc limit 1)
3.列子查询:子查询结果为‘多行一列’,通常可以当做‘多个值’来使用,类似(1,2,3,4)
#查询出在郑州工作的所有员工
select *from empwhere depton in (select depton from dept where loc = '郑州');
4.标量子查询:子查询结果为‘一行一列’,通常可以当做‘一个值’来使用,当做字段使用
1.4 常见的子查询
1.使用比较运算符中使用子查询
#查询部门10中工资大于本部门平均工资的员工
select * from emp where sal >(select avg(sal) from emp where depton=10) AND deptno = 10;
2.使用 in 子查询
#in 如果查询结果集返回多行一列数据,使用in
select * from emp where depton in (select depton from dept where loc='郑州')
3.使用 all 子查询
all可以与=、>、>=、<、<=、<>结合是来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的其中的所有数据。
#查询工资比所有职位为MANAGER工资都高的所有员工
select * from emp where sal >all (select sal from emp where job='MANAGER');
4.使用 any/some 子查询
any 可以与=、>、>=、<、<=、<>结合起来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的任何一个数据。
查询工资比所有职位为MANAGER最低工资高的所有员工
select sal from emp where job='MANAGER';
select * from emp where sal >any(select min(sal) from emp where job='MANAGER');
select * from emp where sal >any (select sal from emp where job='MANAGER');
select * from emp where sal <any (select sal from emp where job='MANAGER');
上面的any可以用some替换
5.使用 exists 和 not exists 子查询
where exist (子查询)如果该子查询有结果数据(无论什么数据,只要大于等于1行),则就为true,否则就为false
select * from emp where exists (select * from dept where loc='郑州')
6.连接查询和子查询的区别
1、MySQL从4.1版本开始支持子查询,使用子查询进行SELECT语句嵌套查询,可以一次完成很多逻辑上需要多个步骤才能完成的SQL操作
2、子查询虽然很灵活,但是执行效率并不高,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,这里多了一个创建和销毁临时表的过程
3、可以使用连接查询(JOIN)代替子查询,连接查询不需要建立临时表,因此其速度比子查询快
二、联合查询
union 合并去重复
union all 合并不去重复
#union ,合并子查询,去掉重复的数据
select * from emp where depton>=10 union select * from emp where depton=20;
#union all ,合并子查询,不去重复
select * from emp where depton>=10;
select * from emp where depton=20;
select * from emp where depton>=10 union all select * from emp where depton=20;
要求两个结果集的字段数量必须相等
三、视图
3.1 视图的概念
视图可以理解为一个虚拟的表,本身不存储数据,所以只能提供查询功能,不能进行数据的删除,修改,添加。作用提供复杂查询的简化存储,一次定义永久生效。
3.2 创建视图
#创建视图
create or replace view v_my_view as select OOO.avgSal,d.dname,d.loc from (select * from (select avg(sal) avgSal, depton from emp group by depton) as xxx where xxx.avgSal > 2000) as OOO,dept d where OOO.depton=d.depton;create or replace view v_emp as select * from emp;select * from v_emp;
#replace是替换的意思,如果已经存在了视图,新的视图替换原来的,如果不加replace,出现错误提示,视图已经存在,不能创建重名的视图。
create or replace view v_emp as select * from emp where comm is not null;
3.3 删除视图
-- 删除视图
drop view v_emp;
3.4 修改视图
-- 修改视图
alter view view_name as select * from dept;
本章总结
子查询:查询里面的查询的查询称为子查询,一般子查询先执行,所以一般写到()里
当需要分布查询的时候,考虑使用子查询
分类:表子查询:子查询返回的是一个结果集(多行多列),就可以把它当成一张表去使用。
行子查询:子查询返回的一行多列(了解)
列子查询:子查询返回一列多行,一列一行(可以作为一个值的where后面),如果是一列多行(要结合all,in,any,some)
联合查询:就是把两个结果集合并在一起 要求是:两个查询的字段数量必须一致
union:去重
union all:不去重
视图: 视图是一张虚表,一般情况下里面保存了一个比较复杂的SQL查询,这样可以简化每次执行复杂的SQL语句