基本统计函数的使用 count(*|字段|[distinct]|常量) max(字段(日期或数字)) min(字段) sum(数字字段) avg(数字字段) |
--查询员工的最高工资和最低工资 select max(sal),min(sal) from emp e; --查询最晚和最早被雇佣的员工日期 select max(e.hiredate),min(e.hiredate) from emp e; --统计所有员工的总工资已经平均工资 select sum(e.sal),avg(e.sal) from emp e; ---统计员工的平均服务年限 select trunc(avg(months_between(Sysdate,e.hiredate))/12) from emp e; |
count(*),count(字段),count(distinct 字段)的区别; 1.count(*):明确的返回表中的数据个数;是最准确的; 2.count(字段):不统计为null的数据个数,如果某一列的数据不可能为空, 那么结果与 count(*)相同; 3.count(distinct 字段):统计消除重复数据后的数据个数 4.COUNT(常量) 和 COUNT(*)表示的是直接查询符合条件的数据库表的行数, 推荐使 用count(*); |
语法结构 分组统计查询 【5.确定要使用的数据列】select [distnct]分组字段[别名],....|统计函数 【1.确定数据来源】from 表名1 [cross join tableName2] [natural join tableName2] [join tableName on(条件)|using(字段)] [left|right|full outer join tableName2] 【2.针对数据行进行筛选】[where 条件] 【3.针对数据实现分组操作】[group by 分组字段,分组字段,....] 【4.针对分组后的数据进行过滤】[having 分组后的过滤条件] 【6.针对返回的结果进行排序】order by 字段[asc|desc,...] |
---按照职位分组,统计每个职位的名称,人数,平均工资; select job,count(*),avg(sal) from emp group by job; ---要求查询出每个部门编号,以及每个部门的人数、最高和最低工资 select c.deptno,count(*),max(sal),min(sal) from emp c group by c.deptno; |
---分组统计查询的限制 1.在没有编写group by 子句的时候(全部作为一组),那么select子句中 只允许出现统计函数,不允许出去任何的其他字段 错误写法: select count(*),ename from emp; 2.在使用group by字句分组的时候,select子句之中 只允许出现分组字段和统计函数,其他字段不允许出现; 错误写法:select job,count(*),ename from emp e group by job; 3.统计查询允许嵌套查询,但是嵌套后的统计查询中,select子句里 不允许再出现任何的字段,包括分组字段,只能使用嵌套的统计函数; 错误写法: select e.deptno,Max(avg(sal)) from emp e group by deptno; 正确写法 select Max(avg(sal)) from emp e group by deptno; |
---分组查询(多表查询) 步骤: 1.确定要使用的数据表 2.确定已知的关联字段; |
--查询每个部门的名称,平均工资,人数 select d.dname,avg(sal),count(*) from emp e ,dept d where e.deptno(+)=d.deptno group by d.dname; --查询每个部门的部门编号,部门名称,位置,部门人数,平均服务年限 select d.deptno,d.dname,d.loc,count(*),trunc(avg(months_between(sysdate,e.hiredate)/12)) from dept d, emp e where d.deptno=e.deptno group by d.deptno,d.dname,d.loc --查询出平均工资高于2000的职位和平均工资 --错误代码: select e.job,avg(sal) from emp e where avg(sal)>2000 group by e.job; --where子句上不允许使用分组函数, --之所以不能允许,是因为统计的操作是属于Group by子句之后的范畴了; ---where子句是在group by操作之前使用的;此时如果要针对于分组后的的数据进行过滤,需要使用having 子句完成 --正确的代码 select e.job,avg(sal) from emp e group by e.job having avg(sal)>2000;
|
--1.where和having的区别? --a.where 发生在Group by操作之前,属于分组前的数据筛选;where子句不允许使用统计函数; --b.having 发生在Group by 操作之后,属于分组后的数据筛选;having子句可以使用统计函数; |
---显示非销售人员工作名称以及从事同一工作雇员的月工资的总和, 并且满足 从事同 一工作雇员的月工资的总和高于¥5000,输出结果按工资的 合计升序排 列; select e.job,sum(sal) num from emp e where job!='SALESMAN' group by job having sum(sal)>5000 order by num asc; ---统计所有领取佣金和不领取佣金的雇员人数和平均工资
错误代码 select e.comm,count(*),avg(sal) from emp e group by comm; --*在分组的时候需要注意只有基数(列的值)固定的时候才可以分组 select '领取佣金' title,count(*),avg(sal) from emp e where e.comm is not null union select '不领取佣金' title,count(*),avg(sal) from emp e where e.comm is null; |
总结 1.不管是单表分组还是多表分组,重点看重复列,如果是一个重复列在group by后加一个字段,如果有多个重复再group by后添加多个字段; 2.分组中的使用限制: a.分组函数嵌套后不允许出现任何字段; b在使用group by字句分组的时候,select子句之中 只允许出现分组字段和统计函数,其他字段不允许出现; 3.多表查询与分组统计查询的时候相当于是一张临时表,所有的分组是在这种临时表中完成的; |