16 group by 和 having

16 group by 和 having
 
    group by:按照某个字段或者某些字段进行分组。
    having:having是对分组之后的数据进行再次过滤。
    
    案例:找出每个岗位的最高薪资。
    select max(empno) as '员工编号',max(ename) as '员工薪资',max(sal) as '最高工资' from emp group by job;
        +----------+----------+----------+
        | 员工编号 | 员工薪资 | 最高工资 |
        +----------+----------+----------+
        |     7902 | SCOTT    |  3000.00 |
        |     7934 | SMITH    |  1300.00 |
        |     7782 | JONES    |  2975.00 |
        |     7839 | KING     |  5000.00 |
        |     7844 | WARD     |  1600.00 |
        +----------+----------+----------+
        
        
        
        注意:分组函数一般都会和group by 联合使用。这也是为什么他被称为分组函数的原因。
        并且任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的。
        当一条sql语句没有group by 的话,整张表的数据会自成一组。
        
        select ename,max(sal),job from emp group by job;
        以上的mysql当中,查询结果是有的,但是结果没有意义,在orcale数据库当中会报错。语法错误。
        orcale的语法规则比mysql语法规则严谨。
        
        记住一个规则:当一条语句中有group by的话,select后面只能跟分组函数和参与分组的字段。
        
        每个工作岗位的平均薪资?
            select job,avg(sal) from emp group by job;
                +-----------+-------------+
                | job       | avg(sal)    |
                +-----------+-------------+
                | ANALYST   | 3000.000000 |
                | CLERK     | 1037.500000 |
                | MANAGER   | 2758.333333 |
                | PRESIDENT | 5000.000000 |
                | SALESMAN  | 1400.000000 |
                +-----------+-------------+
                
        过个字段能不能联合起来一起分组?
        案例:找出每个部门不同岗位的最高薪资。
            select max(sal),deptno,job from emp group by deptno,job;
                +----------+--------+-----------+
                | max(sal) | deptno | job       |
                +----------+--------+-----------+
                |  1300.00 |     10 | CLERK     |
                |  2450.00 |     10 | MANAGER   |
                |  5000.00 |     10 | PRESIDENT |
                |  3000.00 |     20 | ANALYST   |
                |  1100.00 |     20 | CLERK     |
                |  2975.00 |     20 | MANAGER   |
                |   950.00 |     30 | CLERK     |
                |  2850.00 |     30 | MANAGER   |
                |  1600.00 |     30 | SALESMAN  |
                +----------+--------+-----------+
 
        找出每个部门的最高薪资,要求显示薪资大于2900的数据。
        
            第一步:找出每个部门的最高薪资
            第二步:找出薪资大于2900的
                
            select deptno,max(sal) from emp group by deptno having max(sal) > 2900; // 这种方式效率低
                +--------+----------+
                | deptno | max(sal) |
                +--------+----------+
                |     10 |  5000.00 |
                |     20 |  3000.00 |
                +--------+----------+
            
            // 建议使用这种方式 效率较高 能够使用where过滤的就用where条件
            select deptno,max(sal) from emp where sal > 2900 group by deptno;
                +--------+----------+
                | deptno | max(sal) |
                +--------+----------+
                |     10 |  5000.00 |
                |     20 |  3000.00 |
                +--------+----------+
                
        找出每个部门的平均薪资,要求显示薪资大于2000的数据。
            
            第一次:找出每个部门的平均薪资
            select deptno,avg(sal) from emp group by deptno;
                +--------+-------------+
                | deptno | avg(sal)    |
                +--------+-------------+
                |     10 | 2916.666667 |
                |     20 | 2175.000000 |
                |     30 | 1566.666667 |
                +--------+-------------+
            
            第二步:要求显示平均薪资大于2000的数据。
        
            select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;
                +--------+-------------+
                | deptno | avg(sal)    |
                +--------+-------------+
                |     10 | 2916.666667 |
                |     20 | 2175.000000 |
                +--------+-------------+
        
            where后面不能使用分组函数:
                select deptno,avg(sal) from emp where avg(sal) > 2000 group by deptno; // 错误了
                这种情况只能使用having过滤。
原文地址:https://www.cnblogs.com/xlwu/p/13639543.html