欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Oracle_4th_分组(group by)和筛选(having)

程序员文章站 2022-07-13 16:08:28
...
一、group by语句
求一张雇员表中平均的薪水很简单:
select avg(sal) from emp;
但如果要列出不同部门的平均薪水,需要用到group by语句, group by + 分组所依据的字段:
select deptno, avg(sal) from emp group by deptno;
    DEPTNO   AVG(SAL)
---------- ----------
        30 1566.66667
        20       2175
        10 2916.66667

可以依赖两个字段来进行分组,根据两个字段的组合来判别是不是一组:
select deptno, job, avg(sal) from emp group by deptno, job;
    DEPTNO JOB         AVG(SAL)
---------- --------- ----------
        20 CLERK            950
        30 SALESMAN        1400
        20 MANAGER         2975
        30 CLERK            950
        10 PRESIDENT       5000
        30 MANAGER         2850
        10 CLERK           1300
        10 MANAGER         2450
        20 ANALYST         3000

如果要查询挣钱最多的那个人的名字,尝试下面的语句:
select ename, max(sal) from emp;
提示:
select ename, max(sal) from emp
       *
第 1 行出现错误:
ORA-00937: 不是单组分组函数

这是因为max(sal)只返回一个值5000,但这个值可能对应于多个ename,也就是无法保证只有一个sal为5000的员工。

这种情况需要用到子查询:
select ename from emp where sal = (select max(sal) from emp);
ENAME
----------
KING

每一个部门里,挣钱最多的那个人的名字:
select deptno, max(sal) from emp group by deptno;
    DEPTNO   MAX(SAL)
---------- ----------
        30       2850
        20       3000
        10       5000

总结:
①组函数以外的select列表里的字段,必须出现在group by中。
②如果使用了group by进行了分组,则select列表中的字段必须有组函数。
③如果要对分组的后的结果再进行筛选,不能使用where,应该使用having。


二、having语句
having对分组结果进行筛选。
1)根据deptno字段内容进行分组,计算若干组平均薪水,并且这些平均薪水必须大于2000。
select avg(sal), deptno from emp group by deptno having avg(sal) > 2000;
  AVG(SAL)     DEPTNO
---------- ----------
      2175         20
2916.66667         10

查询工资大于1200的雇员,按部门编号进行分组,分组后平均薪水大于1500,按工薪倒充排列:
select avg(sal) from emp where sal > 1200 group by deptno having avg(sal) > 1500 order by avg(sal) desc;
  AVG(SAL)
----------
2991.66667
2916.66667
      1690


三、综合举例

下面是对oracle系列博客所学查询语句的一个综合应用:

Oracle_4th_分组(group by)和筛选(having)