• oracle实验17:分组统计函数


    分组函数

    是对表中一组记录进行操作,每组只返回一个结果。即首先要对表记录进行分组,然后再进行操作汇总,每组返回一个结果。分组时可能是整个表分为一组,也可能根据条件分成多组。

    oracle实验17:分组统计函数

    分组函数常用到以下的五个函数:

    –MIN 最小值 MIN([DISTINCT|ALL]表达式)
    –MAX 最大值 MAX([DISTINCT|ALL]表达式)
    –SUM 求和 SUM([DISTINCT|ALL]n)
    –AVG 平均 AVG([DISTINCT|ALL]n)
    –COUNT 计数 COUNT({*|[DISTINCT|ALL]表达式})

     

    求工资总和,最低工资,最高工资,平均工资,工资计数。

    SQL> select sum(sal),min(sal),max(sal),avg(sal),count(sal) from emp;

      SUM(SAL)   MIN(SAL)   MAX(SAL)   AVG(SAL) COUNT(SAL)
    ---------- ---------- ---------- ---------- ----------
         24930        801       5000     2077.5         12


    日期的最小和最大

    SQL> select min(hiredate),max(hiredate) from emp;

    MIN(HIREDATE)  MAX(HIREDATE)
    -------------- --------------
    17-12月-80     23-1月 -82

    日期的小为早,大为晚。


    count(*)查有多少行包含空行,count(列名)查非空的行。

    SQL>  select count(*),count(comm) from emp;

      COUNT(*) COUNT(COMM)
    ---------- -----------
            12           4

     

    组函数中空值处理

    所有组函数,除了count(*),都忽略空值。


    求平均奖金

    SQL> select avg(comm),avg(nvl(comm,0)) from emp;

     AVG(COMM) AVG(NVL(COMM,0))
    ---------- ----------------
           550       183.333333

    AVG(COMM)奖金非空的人的平均值;
    AVG(NVL(COMM,0))所有人奖金的平均值,如果奖金为空,按0计算。

    SQL> select sum(comm),count(comm),count(*) from emp;

     SUM(COMM) COUNT(COMM)   COUNT(*)
    ---------- ----------- ----------
          2200           4         12

     

    SUM和AVG函数都是只能够对数字类型的列或表达式操作。

    SQL> select sum(ename) from emp;
    select sum(ename) from emp
               *
    第 1 行出现错误:
    ORA-01722: 无效数字

    DISTINCT会消除重复记录后再使用组函数

    SQL> select count(distinct deptno) from emp;

    COUNT(DISTINCTDEPTNO)
    ---------------------
                        3
    计算有多少不同部门代码数。


    GROUP BY子句

    语法:

    SELECT列名, 组函数(列名)
    FROM表名
    [WHERE条件]
    [GROUP BY分组列]
    [ORDER BY列名];

    组函数忽略空值,可以使用NVL,NVL2,COALESCE 函数处理空值

    结果集隐式按升序排列,如果需要改变排序方式可以使用Order by 子句

     

    SQL> select deptno ,sum(sal) from emp group by deptno;

        DEPTNO   SUM(SAL)
    ---------- ----------
            30       9402
            20       6778
            10       8750


    在GROUP BY子句使用中,有两点需要注意:

    –GROUP BY子句后的列可以不在SELECT语句中出现,有利于子查询。
    –SELECT子句中出现的非分组函数列必须在GROUP BY子句中出现。

    SQL> select sum(sal) from emp group by deptno;

      SUM(SAL)
    ----------
          9402
          6778
          8750

    SQL> select deptno ,sum(sal) from emp;
    select deptno ,sum(sal) from emp
           *
    第 1 行出现错误:
    ORA-00937: 不是单组分组函数

    deptno要求每行都显示,而sum要求多行统计后再显示,违反了原则。

     

    多列分组,每列都一样才放到一组。

    SQL> select deptno,job,sum(sal) from emp group by deptno,job;

        DEPTNO JOB         SUM(SAL)
    ---------- --------- ----------
            20 CLERK            801
            30 SALESMAN        5602
            20 MANAGER         2975
            30 CLERK            950
            10 PRESIDENT       5000
            30 MANAGER         2850
            10 CLERK           1300
            10 MANAGER         2450
            20 ANALYST         3002

    已选择9行。

    30号部门中有4个销售,合并成一行。


    SQL> select job,avg(sal) from emp group by job;

    JOB         AVG(SAL)
    --------- ----------
    CLERK           1017
    SALESMAN      1400.5
    PRESIDENT       5000
    MANAGER   2758.33333
    ANALYST         3002


    SQL> select job,avg(sal) from emp
         where avg(sal)>2000
         group by job;
    where avg(sal)>2000
          *
    第 2 行出现错误:
    ORA-00934: 此处不允许使用分组函数

    不能执行,原因是where是条件,avg(sal)是结果。条件中使用了结果,违反了因果关系。

    Oracle查询语句的执行顺序是:–FROM WHERE GROUP BY SELECT ORDER BY

    HAVING子句

    语法:

    SELECT列名, 组函数
    FROM表名
    [WHERE条件]
    [GROUP BY分组列]
    [HAVING组函数表达式]
    [ORDER BY列名];

    HAVING是在结果中再次筛选,HAVING一定要出现在group by子句的后面,不能独立存在。

     

    SQL> select job,avg(sal) from emp group by job having avg(sal)>2000;

    JOB         AVG(SAL)
    --------- ----------
    PRESIDENT       5000
    MANAGER   2758.33333
    ANALYST         3002

    SQL> select deptno,JOB,sal from emp where job='SALESMAN' or job='CLERK' ;

        DEPTNO JOB              SAL
    ---------- --------- ----------
            20 CLERK            801
            30 SALESMAN        1601
            30 SALESMAN        1250
            30 SALESMAN        1250
            30 SALESMAN        1501
            30 CLERK            950
            10 CLERK           1300

    已选择7行。

    SQL> select deptno,avg(sal) from emp
         where job='SALESMAN' or job='CLERK'
         group by deptno
         having avg(sal)>1000;

        DEPTNO   AVG(SAL)
    ---------- ----------
            30     1310.4
            10       1300

    where和having可以同时出现在一句话中,起作用的时间不同。

    总结SELECT语句执行过程:

    –通过FROM子句中找到需要查询的表;
    –通过WHERE子句进行非分组函数筛选判断;
    –通过GROUP BY子句完成分组操作;
    –通过HAVING子句完成组函数筛选判断;
    –通过SELECT子句选择显示的列或表达式及组函数;
    –通过ORDER BY子句进行排序操作。

    组函数的嵌套

    组函数可以实现嵌套操作,组函数的嵌套要使用group by子句,嵌套级数是2级。

    SQL> select max(avg(sal)) from emp group by deptno;

    MAX(AVG(SAL))
    -------------
       2916.66667

    求各个部门平均工资的最大值。

     

    巧用decode函数,改变排版方式。

    SQL> select sum(decode(to_char(hiredate,'yyyy'),'1980',1,0)) "1980",
                sum(decode(to_char(hiredate,'yyyy'),'1981',1,0)) "1981",
                sum(decode(to_char(hiredate,'yyyy'),'1982',1,0)) "1982",
                sum(decode(to_char(hiredate,'yyyy'),'1987',1,0)) "1987",
                count(ename) "总人数"
         from emp;

          1980       1981       1982       1987     总人数
    ---------- ---------- ---------- ---------- ----------
             1         10          1          0         12

    知识点:

    • 组函数
    • 分组统计
    • null值在组函数中的作用
    • having的过滤作用
    • 组函数的嵌套

    返回目录  http://www.cnblogs.com/downpour/p/3155689.html

  • 相关阅读:
    CF353D Queue(结论)
    CF1147C Thanos Nim(博弈论、结论推导)
    牛客:CBX and children(平衡树+二分+贪心)
    牛客:Gambling Monster(权值线段树+离散化+离线)
    剑指49.把字符串转换成整数
    剑指48.不用加减乘除做加法
    剑指47.求1+2+3+...+n
    剑指46.孩子们的游戏(圆圈中最后剩下的数字)
    剑指45.扑克牌顺子
    剑指44.翻转单词顺序
  • 原文地址:https://www.cnblogs.com/downpour/p/3157396.html
Copyright © 2020-2023  润新知