ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

【MySQL】十一、分组函数(group by,having),多字段分组查询

2021-02-16 20:00:10  阅读:272  来源: 互联网

标签:group sal max job 分组 薪资 deptno 多字段


文章目录

前言

group by:按照某个字段或者某些字段进行分组;
having:对分组之后的数组进行再次过滤;

1. group by

1.1 案例1:找出每个工作岗位的最高薪资。

select job,max(sal) from emp group by job;

这条sql语句的意思是,先对每个job进行分组,然后对每一组中求最大值。

执行顺序:先执行from,然后执行group by,最后select。

分组函数一般都会和group by联合使用!这也是为什么它被称为分组函数的原因。

任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的!

任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的!

任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的!

当一条sql语句没有group by,整张表的数据会自成一组。

下sql语句没有使用group by,但是存在一个缺省的group by。

select avg(sal) from emp;

查询结果:

+-----------+----------+
| job       | max(sal) |
+-----------+----------+
| ANALYST   |  3000.00 |
| CLERK     |  1300.00 |
| MANAGER   |  2975.00 |
| PRESIDENT |  5000.00 |
| SALESMAN  |  1600.00 |
+-----------+----------+
5 rows in set (0.00 sec)

对于上案例,我们已经知道了每个工作岗位上的最高工资,但是我们想进一步知道最高工资对应的人名,似乎我们可以写成以下语句:

select ename, job, max(sal) from emp group by job;

查询结果:

+-------+-----------+----------+
| ename | job       | max(sal) |
+-------+-----------+----------+
| SCOTT | ANALYST   |  3000.00 |
| SMITH | CLERK     |  1300.00 |
| JONES | MANAGER   |  2975.00 |
| KING  | PRESIDENT |  5000.00 |
| ALLEN | SALESMAN  |  1600.00 |
+-------+-----------+----------+
5 rows in set (0.00 sec)

这条语句的执行结果显然是不正确的! SMITH 的工资是800,这里成了1300。

这条语在MySQL中是可以执行的,但是在Oracle中是无法执行(语法错误,Oracle的语法比MySQL严谨)。即使MySQL中可以执行,但是结果毫无意义。

记住一个规则:

当一条语句中有group by ,select 后面只能跟分组函数和参与分组的字段。

1.2 案例2:找出每个工作岗位的平均薪资

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 |
+-----------+-------------+
5 rows in set (0.00 sec)

1.3 案例3:找出每个部门不同工作岗位的最高薪资(多字段分组查询)

我们先看下不同部门,不同岗位上员工工资信息;

select deptno,ename,job,sal from emp;

查询结果:

+--------+--------+-----------+---------+
| deptno | ename  | job       | sal     |
+--------+--------+-----------+---------+
|     10 | MILLER | CLERK     | 1300.00 |
|     10 | CLARK  | MANAGER   | 2450.00 |
|     10 | KING   | PRESIDENT | 5000.00 |

|     20 | SCOTT  | ANALYST   | 3000.00 |
|     20 | FORD   | ANALYST   | 3000.00 |
|     20 | SMITH  | CLERK     |  800.00 |
|     20 | ADAMS  | CLERK     | 1100.00 |
|     20 | JONES  | MANAGER   | 2975.00 |

|     30 | JAMES  | CLERK     |  950.00 |
|     30 | BLAKE  | MANAGER   | 2850.00 |
|     30 | ALLEN  | SALESMAN  | 1600.00 |
|     30 | WARD   | SALESMAN  | 1250.00 |
|     30 | MARTIN | SALESMAN  | 1250.00 |
|     30 | TURNER | SALESMAN  | 1500.00 |
+--------+--------+-----------+---------+
14 rows in set (0.00 sec)
select deptno, job, max(job) from emp group by deptno, job;

查询结果:

+--------+-----------+----------+
| deptno | job       | max(sal) |
+--------+-----------+----------+
|     10 | CLERK     |  1300.00 |
|     10 | MANAGER   |  2450.00 |
|     10 | PRESIDENT |  5000.00 |
|     20 | ANALYST   |  3000.00 |
|     20 | CLERK     |  1100.00 |
|     20 | MANAGER   |  2975.00 |
|     30 | CLERK     |   950.00 |
|     30 | MANAGER   |  2850.00 |
|     30 | SALESMAN  |  1600.00 |
+--------+-----------+----------+
9 rows in set (0.00 sec)

2. having 和where

2.1 案例1:找出每个部门的最高薪资,要求薪资大于2900的数据

第一步:找出每个每个部门的最高薪资;

select max(sal), deptno from emp group by deptno;

查询结果:

+----------+--------+
| max(sal) | deptno |
+----------+--------+
|  5000.00 |     10 |
|  3000.00 |     20 |
|  2850.00 |     30 |
+----------+--------+
3 rows in set (0.00 sec)

第二步:找出薪资大于2900的;

select max(sal), deptno from emp group by deptno having max(sal) > 2900;
+----------+--------+
| max(sal) | deptno |
+----------+--------+
|  5000.00 |     10 |
|  3000.00 |     20 |
+----------+--------+

这种方式可以查询到结果,但是这种方式的效果是极其低的!我们可以使用以下这种方式:

select sal, deptno from emp where sal > 2900 group by deptno;

先把薪资小于2900的信息过滤掉,然后再分组,这种执行效率就会更快一些!

因此,建议能够使用where过滤的尽量使用where。

2.2 案例2:找出每个部门的平均薪资,要求显示薪资大于2000的数据

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

查询结果:

+-------------+--------+
| avg(sal)    | deptno |
+-------------+--------+
| 2916.666667 |     10 |
| 2175.000000 |     20 |
+-------------+--------+
2 rows in set (0.00 sec)

这里只能使用having过滤,不能使用where关键字。以下写法是错误的,因为where后面是不能跟分组函数的。

select  avg(sal), deptno from emp  where avg(sal) > 2000 group by deptno; // 错误

标签:group,sal,max,job,分组,薪资,deptno,多字段
来源: https://blog.csdn.net/weixin_43519707/article/details/113818946

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有