DQL
1.关键字顺序
select…
from…
where…
group by…
having…
order by…
limit…
执行顺序:
- from
- where
- group by
- having
- select
- order by(排序总在最后执行)
- limit…
2.单行处理函数
NULL只要参与运算,最终结果一定是NULL。为了避免这个现象,需要使用ifnull函数
ifnull函数用法:ifnull(数据,被当做哪个值)。
当comm为NULL的时候,将补助当作0
select ename,(sal+ifnull(comm,0)) * 12 as yearsal from emp;
3.分组函数(多行处理函数、聚合函数)
分组函数用之前必须先分组,如果没分组,整张表默认为一组
5个:
- count 计数
- sum 求和
- avg 平均值
- max 最大值
- min 最小值
注:
分组函数自动忽略NULL,不需要提前对NULL进行处理
count(具体字段):表示统计该字段下所有不为NULL的元素的总数
。count(*):统计表当中的总行数。(只要有一行数据count则++)因为每一行记录不可能都为NULL,一行数据中有一列不为NULL,则这行数据就是有效的
分组函数不能够直接使用在where子句中
找出比最低工资高的员工信息
select ename,sal from emp where sal > min(sal) 报错
思考1:为什么分组函数不能够直接使用在where后面?
select ename,sal from emp where sal > min(sal)
因为分组函数在使用的时候必须先分组之后才能使用。where执行的时候,还没有分组。所以where后面不能出现分组函数
思考2:select sum(sal) from emp;这个没有分组,为啥sum( )函数可以用呢?
因为select在group by之后执行
4.分组查询
group by
select ename,job,sum(sal) from emp group by job;
以上语句在mysql中可以执行,但是毫无意义。
以上语句在oracle中执行报错
结论:在一条select语句中,如果有group by语句的话,select后面只能跟:参加分组的字段,以及分组函数,其他的一律不能跟
having
使用having可以对分完组之后的数据进一步过滤。having不能单独使用,having不能代替where,having必须和group by联合使用
优化策略:where 和 having,优先选择where,where实在完成不了了,再选择having
distinct
把查询结果去除重复记录。distinct只能出现在所有字段的最前方
5.连接查询
分类
根据表连接的方式分类:
内连接:
- 等值连接
- 非等值连接
- 自连接
外连接:
- 左外连接(左连接)
- 右外连接(右连接)
全连接
多表连接
语法:
select
…
from
a
join
b
on
a和b的连接条件
join
c
on
a和c的连接条件
right join
d
on
a和d的连接条件
一条SQL中内连接和外连接可以混合。都可以出现
6.子查询
select语句中嵌套select语句,被嵌套的select语句称为子查询
子查询可以出现的位置:
select
…(select)
from
…(select)
where
…(select)
where子句中的子查询
案例:找出比最低工资高的员工姓名和工资
第一步:查询最低工资是多少
select min(sal) from emp;
第二步:合并
select ename,sal from emp where sal > (select min(sal) from emp);
from子句中的子查询
注意:from后面的子查询,可以将子查询的查询结果当做一张临时表
案例:找出每个岗位的平均工资的薪资等级
第一步:找出每个岗位的平均工资(按照岗位分组求平均值)
select job,avg(sal) from emp group by job;
第二步:克服心理障碍,把以上的查询结果就当作一张真实存在的表
select t.*,s.grade
from
(select job,avg(sal) as avgsal from emp group by job) t
join
salgrade s
on
t.avgsal 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;
7.union
union的效率要高一些,相对表连接来说。union 会对合并之后的数据去重。
注意事项:
-
union在进行结果集合并的时候,要求两个结果集的列数相同
select ename,job from emp where job = 'MANAGER' union select ename from emp where job = 'SALESMAN';
报错
-
要求结果集合并列和列的数据类型也要一致
select ename,job from emp where job = 'MANAGER' union select ename,sal from emp where job = 'SALESMAN';
mysql可以,oracle报错
8.limit
作用:将查询结果集的一部分取出来。通常使用在分页查询当中。
完整用法:limit startIndex,length.
startIndex是起始下标,length是长度。起始下标从0开始
缺省用法:limit 5;这是取前5
select ename,sal from emp order by sal desc limit 0,5;
注意:mysql当中limit在order by之后执行
分页公式:limit (pageNo-1)* pageSize , pageSize