五.分组函数/多行处理函数
5.1多行处理函数的特点:输入多行,最终输出一行
count 计数
sum 求和
avg 平均值
max 最大值
min 最小值
注意:
分组函数在使用的时候必须先进行分组,然后才能使用。
如果你没有对数据进行分组,整张表默认为一组,如下:
找出最高工资?
select
max(sal)
from
emp;
找出最低工资?
select
min(sal)
from
emp;
计算工资和?
select
sum(sal)
from
emp;
计算平均工资?
select
avg(sal)
from
emp;//14个工资全部加起来,然后除以14
计算员工数量?
select
count(ename)
from
emp;
5.2分组函数在使用时需要注意什么
(1)分组函数自动忽略NULL,你不需要提前对NULL进行处理。
(2)分组函数中count(*)和count(具体字段)有什么区别:
count(*):统计表当中的总行数,只要有一行数据,count则++,因为每一行记录不可能都为NULL,一行数据中有一列不为NULL,则这行数据就是有效的。
count(具体字段):表示统计该字段下所有不为NULL的元素的总数。
(3)分组函数不能够直接使用在where子句中。
找出比最低工资高的员工信息:
select
ename,sal
from
emp
where
sal > min(sal);
表面上没问题,运行显示ERROR 1111(HY000)报错,讲完分组查询group by就明白了。
(4)所有的分组函数可以组合起来一起用
select
sum(sal),min(sal),max(sal),avg(sal),count(*)
from
emp;
5.3分组查询(非常重要,五颗星***)**
在实际的应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作,这个时候我们需要使用分组查询,怎么进行分组查询呢?
select
...
from
...
group by
...
将之前的关键字全部组合在一起,来看一下它们的执行顺序?
select
...
from
...
group by
...
order by
...
以上关键字的顺序不能颠倒,需要记忆,执行的顺序:
1.from
2.where
3.group by
4.select
5.order by
为什么分组函数不能直接使用在where后面?
select ename,sal from emp where sal > min(sal);//报错
**因为分组函数在使用的时候必须先分组之后才能使用,where执行的时候,还没有分组,所以where后面不能出现分组函数。
select sum(sal) from emp;
这个没有分组,为啥sum()函数可以用呢?因为select在group by之后执行。
例1:找出每个工作岗位的工资和?
实现思想:按照工作岗位分组,然后对工资求和。
select
job,sum(sal)
from
emp
group by
job;
以上语句的执行顺序是:先从emp表中查询数据,根据job字段进行分组,然后对每一组的数据进行sum(sal)
select ename,job,sum(sal) from emp group by job;
以上语句在mysql中可以执行,但是毫无意义,在oracle中执行报错,oracle的语法比mysql的语法严格
重点结论:在一条select语句中,如果有group by语句的话,select后面只能跟参加分组的字段,以及分组函数,其他一律不能跟,比如这条语句中的ename就不应该写在select后面。
例2:找出每个部门的最高薪资?
实现思想:按照部门编号分组,求每一组的最大值。
select
deptno,max(sal)
from
emp
group by
deptno;
例3:找出每个部门,不同岗位的最高薪资?
技巧:两个字段联合成1个字段看(两个字段联合分组)
select
deptno,job,max(sal)
from
emp
group by
deptno,job;
\
例4:找出每个部门最高薪资,要求显示最高薪资大于3000的?
第一步:找出每个部门最高薪资
按照部门编号分组,求每一组最大值。
select
deptno,max(sal)
from
emp
group by
deptno;
第二步:要求显示最高薪资大于3000
使用having语句可以对分完组之后的数据进一步过滤。having不能单独使用,having不能代替where,having必须和group by联合使用。
select
deptno,max(sal)
from
emp
group by
deptno;
having
max(sal)>3000;
思考一个问题:以上的sql语句执行效率是不是低?
比较低,实际上可以这样考虑,先将大于3000的都找出来,然后在分组。
select
deptno,max(sal)
from
emp
where
sal>3000
group by
deptno;
优化策略:where和having,优先选择where,where实在完成不了了,再选择having。
例5:找出每个部门的平均薪资,要求显示平均薪资高于2500的?(只能用having,不能用where的情况)
第一步:找出每个部门的平均薪资
select
deptno,avg(sal)
from
emp
group by
deptno;
第二步:要求显示平均薪资高于2500的
select
deptno,avg(sal)
from
emp
group by
deptno
having
avg(sal) > 2500;
5.3大总结(单表查询)
select
...
from
...
where
...
group by
...
having
...
order by
...
以上关键字只能按照这个顺序来,不能颠倒。
执行顺序?
1.from
2.where
3.group by
4.having
5.select
6.order by
从某张表中查询数据,
先经过where条件筛选出有价值的数据,
对这些有价值的数据进行分组,
分组之后可以使用having继续筛选,
最后排序输出。
找出每个岗位的平均薪资,要求显示平均薪资大于1500的,除manager之外,要求按照平均薪资降序排。
select
job,avg(sal) as avgsal
from
emp
where
job <> 'manager'
group by
job
having
avg(sal) > 1500
order by
avgsal desc;