回顾:
1、基本查询语句
select 字段名1....
from 表名
where 条件
from 范围 → where 条件 → select 查询
2、查询条件
3、order by子句
排序
正课:
1、聚合函数
查询时需要做一些数据统计,如:平均值、最大最小值,求和
像这些必须对表中数据进行统计、计算、分析返回一个结果。
这些值是没有办法非常直观的列出,而是根据现有的数据,
经过分析得到相应的结果。
****多行数据,经过统计分析得到一个结果。
因为聚合函数是对于多行数据记录,进行统计分析返回
一行数据,所以又被称为:多行函数、集合函数、组函数。
1)、max、min
max(column):对指定字段,进行统计分析,
得到最大值。
min(column):对指定字段,进行统计分析,
得到最小值。
--所有员工的薪资最大值。
select max(sal) from emp;
--30部门员工的薪资最大值。
select max(sal) from emp where deptno = 30;
--30部门最高薪资的员工信息。
select * from emp where sal = (
--30部门的最高工资
select max(sal)
from emp
where deptno = 30
) and deptno = 30;
错误的sql-1:
select *,max(sal) from emp where deptno = 30;
分析:
--查询30部门员工信息(返回多条数据)
select * from emp where deptno = 30;
--查询30部门最高工资(返回1条数据)
select max(sal) from emp where deptno = 30;
错误的sql-2:
分析:
--max(sal)是对员工薪资统计分析之后得到的结果。
--第一次max(sal)必须在select后面。
--即聚合函数不能出现在条件查询中。
select * from emp
where sal = max(sal)
and deptno = 30;
错误的sql-3:
分析
--薪资等于30部门的最高工资的员工信息
select * from emp where sal = (
--30部门的最高工资
select max(sal)
from emp
where deptno = 30
);
2)、sum、avg
sum(column):对指定字段,进行统计分析
得到总和。
avg(column):得到平均值
--所有员工薪资总和
select sum(sal) 工资总和 from emp;
--30部门的薪资总和
select sum(sal) 30部门工资总和
from emp where deptno = 30;
--查询公司员工平均工资
select avg(sal) 平均工资 from emp;--2073.21
等价于
select sum(sal) / count(sal) from emp;
--将程咬金当成员工进行平均工资统计。
select sum(sal) / count(ename) from emp;
--30部门的平均工资
select avg(sal) "30部门平均工资"
from emp where deptno = 30;
3)、count
count(column):对指定字段进行计数统计
忽略null值的统计。
--公司中有绩效的人数
select count(comm) from emp;
--公司中有工资的人数
select count(sal) from emp;
--统计公司的人数
--只要保证一条记录中,任意一个字段有值,
-- 就算是一条有效的数据记录,使用count(*)。
select count(*) from emp;
总结:聚合函数对null值的处理:忽略。
--查询所有员工的最大工资、最小工资、
-- 平均工资、工资总和。
select max(sal) 最大工资,min(sal) 最小工资,
avg(sal) 平均工资,sum(sal) 工资总和
from emp;
练习:
--查询各部门的最大工资、最小工资、
-- 平均工资、工资总和。
如何实现???
如果看到各部门、每个部门如此的字眼,
请一定要考虑到分组操作。
2、group by子句
group by 字段名1,字段名2...
根据指定字段,对数据记录进行分组操作。
select deptno 部门,max(sal) 最大工资,min(sal) 最小工资,
round(avg(sal)) 平均工资,sum(sal) 工资总和
from emp
group by deptno;--根据部门编号分组,同一个部门编号的为一组。
from 范围 → group by 分组 → 查询 每组的数据。
--查询每个工资的人数。
select sal 工资,count(*) 人数 from emp
where sal is not null
group by sal;
--查询每个部门中姓名及工资。
select deptno 部门,ename 姓名,sal 工资
from emp
group by deptno;
原因既是结论:
a、当一条SQL语句中,出现了group by分组子句时,
则select子句中,只能出现在group by后面的字段
或者是聚合函数。
group by子句意在对数据进行分组操作。
则数据必定是以组为单位进行统计分析。
就无法实现对单条数据做数据显示操作。
b、分组字段如果为多个,如group by 字段名1,字段名2
先按字段名1分组,在分组之后结果数据中,
再按字段名2分组,以此类推。
c、group by子句对应的分组字段,
必定在数据中拥有重复值,否则分组将无意义。
练习:
--相同工资的人数统计。
select sal 工资,count(*) 人数
from emp
where sal is not null
group by sal;
--有相同工资的人数的工资及人数。
select sal 工资,count(*) 人数
from emp
where sal is not null
--and count(*) > 1--where条件查询中不允许出现聚合函数。
group by sal;
3、having子句
二次条件过滤
在对数据进行分组后,对分组的结果数据进行二次条件过滤
--有相同工资的人数的工资及人数。
select sal 工资,count(*) 人数
from emp
where sal is not null
--and count(*) > 1--where条件查询中不允许出现聚合函数。
group by sal --已经分组后就可以使用分组函数了
having count(*) > 1;
注意:
a、having不可能单独出现,必须跟在group by后面。
b、group by分组后,having中可以出现分组函数。
where
--分组
having
having与where的区别?
a、where对查询数据进行一次条件过滤。
where子句中不允许出现分组函数。
b、having对分组后的结果数据进行二次条件过滤。
having子句中允许出现分组函数。