MySQL子查询
子查询:在select语句中嵌套select语句,而被嵌套的select语句被称为子查询。在select,from,where后面都可以出现子查询。
where后的子查询
案例:查询出工资比最低工资高的员工的姓名和工资
select
ename,sal
from
emp
where
sal>min(sal);
上面的这种写法是不行的,因为where子句中不能使用分组函数,我们需要换一种思路。
先进行分步查询
// 第一步,查询最低工资:
select min(sal) from emp;
// 第二步,查询出工资高于最低工资的员工的姓名个工资
select ename,sal from emp where sal>800;
// 第三步,我们把两个查询语句合并为一个,将查询出最低工资的select语句作为查询条件嵌套到第二个select语句中,作为子查询。
select
ename,sal
from
emp
where
sal>(select min(sal) from emp);
form中的子查询
对于from后面的子查询,我们通常将子查询的查询结果当做一张临时表。
案例:找出每个岗位的平均工资的薪资等级
// 第一步,先找出每个岗位的平均工资
select
job,avg(sal)
from
emp
group by
job;
// 第二步,查找薪资等级
select
e.job,s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal;
// 第三步,合并两个查询语句,将平均工资表作为from后面的临时表进行查询
select
t.job,t.sal,s.grade
from
(select job,avg(sal) as sal from emp group by job) t
join
salgrade s
on
t.sal between s.losal and s.hisal;
select后的子查询(了解)
案例:找出每个员工的部门名称,要求显示员工名,部门名
select
e.ename,e.deptno,(select d.dname from dept d where e.deptno=d.deptno) as dname
from
emp e;
当select后的子查询查询出的数据条数多于一条时,就会报错
select
e.ename,e.deptno,(select dname from dept) as dname
from
emp e;
ERROR 1242 (21000): Subquery returns more than 1 row
union合并查询结果集
案例:查询工作岗位是MANAGER和SALESMAN的员工
使用or和in关键字都能实现
select ename,job from emp where job='MANAGER' or job='SALESMAN';
select ename,job from emp where job in ('MANAGER' ,'SALESMAN');
使用union关键字进行查询
select ename,job from emp where job='MANAGER'
union
select ename,job from emp where job='SALESMAN';
和表连接查询相比union的效率要高一些。对于表连接来说,每次连接一次新表,匹配的次数满足笛卡尔积,成倍增加。union可以减少匹配的次数,在减少匹配次数的情况下还能够完成两个结果集的拼接。
union使用时的注意事项
union在进行结果集合并时,要求结果集的列数相同
select ename,job from emp where job='MANAGER'
union
select ename from emp where job='SALESMAN' ;
ERROR 1222 (21000): The used SELECT statements have a different number of columns
结果集合并时列和列的数据类型需要一致
select ename,job from emp where job='MANAGER'
union
select ename,sal from emp where job='SALESMAN' ;
下方的查询是在MySQL中进行的,但是在Oracle中将会报错,因为sal的类型为double,而job的类型为varchar,它们本不能出现在同一字段中。