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

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

 


版权声明:本文为qq_29393273原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。