1.子查询
什么是子查询:select语句中嵌套select语句,被嵌套的select语句就是子查询。
子查询可以出现在哪里:select,from,where
1.1、where后使用子查询
案例:找出高与平均薪资的员工信息
select ename ,sal from emp where sal>(select avg(sal) from emp);
mysql> select ename ,sal from emp where sal>(select avg(sal) from emp);
+-------+---------+
| ename | sal |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
| FORD | 3000.00 |
+-------+---------+
6 rows in set (0.00 sec)
1.2、from后使用子查询
案例:找出每个部门平均薪水的薪资等级。
select e.deptno,s.grade,e.avg(sal)
from
/*1.找出每个部门平均薪水(按照部门编号分组)*/
select deptno,avg(sal) as avgsal from emp group by deptno;
/*2.找出对应的薪资等级*/
select e1.deptno,e1.avgsal,s.grade
from (select deptno,avg(sal) as avgsal from emp group by deptno) e1
join salgrade s on e1.avgsal between s.losal and s.hisal;
/*3.找出对应的部门名称*/
select d.dname,x.avgsal,x.grade
from(select e1.deptno,e1.avgsal,s.grade
from (select deptno,avg(sal) as avgsal from emp group by deptno) e1
join salgrade s on e1.avgsal between s.losal and s.hisal) x
join dept d
on x.deptno = d.deptno;
mysql> select d.dname,x.avgsal,x.grade
-> from(select e1.deptno,e1.avgsal,s.grade
-> from (select deptno,avg(sal) as avgsal from emp group by deptno) e1
-> join salgrade s on e1.avgsal between s.losal and s.hisal) x
-> join dept d
-> on x.deptno = d.deptno;
+------------+-------------+-------+
| dname | avgsal | grade |
+------------+-------------+-------+
| SALES | 1566.666667 | 3 |
| ACCOUNTING | 2916.666667 | 4 |
| RESEARCH | 2175.000000 | 4 |
+------------+-------------+-------+
3 rows in set (0.00 sec)
案例:找出每个部门平均的薪水等级
/*1.先每个人的薪水等级按照*/
select e.deptno ,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
/*2.利用avg 并且分组*/
select t.deptno, avg(t.grade)
from (select e.deptno ,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal) t
group by deptno;
+--------+--------------+
| deptno | avg(t.grade) |
+--------+--------------+
| 20 | 2.8000 |
| 30 | 2.5000 |
| 10 | 3.6667 |
+--------+--------------+
3 rows in set (0.00 sec)
1.3、在select后面使用子查询
案例:找出每个员工所在的部门名称,要求显示员工名和部门名。
select e.ename ,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
mysql> select e.ename ,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
2.union (这个可以将查询结果集相加)
union可以将两个结果集拼接到一起
例如
select ename from emp
union
select dname from dept;
+------------+
| ename |
+------------+
| SMITH |
| ALLEN |
| WARD |
| JONES |
| MARTIN |
| BLAKE |
| CLARK |
| SCOTT |
| KING |
| TURNER |
| ADAMS |
| JAMES |
| FORD |
| MILLER |
| ACCOUNTING |
| RESEARCH |
| SALES |
| OPERATIONS |
+------------+
18 rows in set (0.00 sec)
案例:找出工作岗位是SALESMAN和MANAGER的员工
select ename,job from emp where job = 'MANAGER'
union
select ename,job from emp where job = 'SALESMAN';
+--------+----------+
| ename | job |
+--------+----------+
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)
union可以将两个毫无关系的表 拼接 在一起显示。
表名会用第一个查询结果的名字
注意:union只能将两个 相同列数 的表拼接在一起,不同列数会报错。
3.limit以及通用分页SQL (重点!)
3.1、limit是mysql特有的,其他数据库中没有,不通用(Oracle中有一个相同的机制,叫rownum)
3.2、limit取结果集中的部分数据,这是它的作用。
3.3、语法机制:
limit startIndex,length
startIndex 表示起始位置, length 表示取几个
案例:取出工资前五名 (降序取前五个)
select ename,sal from emp order by sal desc;
select ename,sal from emp order by sal desc limit 0,5;
/*如果前面不写起始位置,那么默认就是0*/
select ename,sal from emp order by sal desc limit 5;
mysql> select ename,sal from emp order by sal desc limit 0,5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.00 sec)
limit是sql语句最后执行的一个环节
语句 | 执行内容 | 执行优先级 |
select … | 查找那些字段 | 5 |
from … | 来自于哪张表 | 1 |
where … | 查找的条件 | 2 |
group by … | 按照什么分组 | 3 |
having … | 分组后还需要过滤什么 | 4 |
order by … | 按照什么顺序来显示 | 6 |
limit … | 取那些数据 | 7 |
3.4、案例:找出工资排名在第4到第9的员工 第4个是从3开始的 4-9是6个
select ename ,sal from emp order by sal desc limit 3,6;
+--------+---------+
| ename | sal |
+--------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
+--------+---------+
6 rows in set (0.00 sec)
3.5、通用的标准SQL
每页显示 3 条记录:
第一页:0, 3
第二页:3, 3
第三页:6, 3
第四页:9, 3
每页显示pageSize条记录:
*第PageNo页:(PageNo-1)pageSize,pageSize
java 代码{
int pageNo = 2; //第 n 页
int pageSize = 10; //每页多少条数据
limit (pageNo - 1) * pageSize , pageSize;
}