Oracle 分组统计查询

基本统计函数的使用
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 字段):统计消除重复数据后的数据个数

语法结构

分组统计查询

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;

扫描二维码关注公众号,回复: 4785215 查看本文章


 ---统计所有领取佣金和不领取佣金的雇员人数和平均工资

错误代码
 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.多表查询与分组统计查询的时候相当于是一张临时表,所有的分组是在这种临时表中完成的;

猜你喜欢

转载自blog.csdn.net/qq_29393273/article/details/84947112