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过滤。