Mysql 分组查询

本文详细介绍了SQL中的分组查询GROUP BY和HAVING子句的使用方法。通过实例展示了如何利用GROUP BY对数据进行分组并计算各组的汇总信息,如求和、最大值等。同时,解释了HAVING子句在不使用分组函数时与WHERE子句的区别,以及在使用分组函数时如何过滤分组后的数据。强调了在能使用WHERE的情况下优先使用WHERE以提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


分组查询主要涉及到两个子句,分别是:group by和having。
group by : 按照某个字段或者某些字段进行分组。
having : having是对分组之后的数据进行再次过滤。

group by

取得每个工作岗位的工资合计,要求显示岗位名称和工资合计。
select job,sum(sal) from emp group by job;

+-----------+----------+
| job       | sum(sal) |
+-----------+----------+
| CLERK     |  4150.00 |
| SALESMAN  |  5600.00 |
| MANAGER   |  8275.00 |
| ANALYST   |  6000.00 |
| PRESIDENT |  5000.00 |
+-----------+----------+

找出每个工作岗位的最高薪资。
select job,max(sal) from emp group by job;

| job       | max(sal) |
+-----------+----------+
| CLERK     |  1300.00 |
| SALESMAN  |  1600.00 |
| MANAGER   |  2975.00 |
| ANALYST   |  3000.00 |
| PRESIDENT |  5000.00 |
+-----------+----------+

如果使用了order by,order by必须放到group by后面
select job,max(sal) from emp group by job order by job desc;

+-----------+----------+
| job       | max(sal) |
+-----------+----------+
| SALESMAN  |  1600.00 |
| PRESIDENT |  5000.00 |
| MANAGER   |  2975.00 |
| CLERK     |  1300.00 |
| ANALYST   |  3000.00 |
+-----------+----------+

在SQL语句中若有group by 语句,那么在select语句后面只能跟分组函数+参与分组的字段。
select job,drptno,sum(sal) from emp group by job,deptno;

+-----------+--------+----------+
| job       | deptno | sum(sal) |
+-----------+--------+----------+
| ANALYST   |     20 |  6000.00 |
| CLERK     |     10 |  1300.00 |
| CLERK     |     20 |  1900.00 |
| CLERK     |     30 |   950.00 |
| MANAGER   |     10 |  2450.00 |
| MANAGER   |     20 |  2975.00 |
| MANAGER   |     30 |  2850.00 |
| PRESIDENT |     10 |  5000.00 |
| SALESMAN  |     30 |  5600.00 |
+-----------+--------+----------+

分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。
并且任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的。
当一条sql语句没有group by的话,整张表的数据会自成一组。

having

不使用分组函数

如果想对分组数据再进行过滤需要使用having子句。
select max(sal),deptno from emp group by deptno having max(sal) > 2900;// 这种方式效率低。

+----------+--------+
| max(sal) | deptno |
+----------+--------+
|  3000.00 |     20 |
|  5000.00 |     10 |
+----------+--------+

select max(sal),deptno from emp where sal > 2900 group by deptno;// 效率较高,建议能够使用where过滤的尽量使用where。

| max(sal) | deptno |
+----------+--------+
|  3000.00 |     20 |
|  5000.00 |     10 |
+----------+--------+

以上两种写法得到的结果是一样的,所以在不使用聚合函数时,having可以看作是where的另一种表达。

使用分组函数

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

+--------+-------------+
| deptno | avg(sal)    |
+--------+-------------+
|     20 | 2175.000000 |
|     10 | 2916.666667 |
+--------+-------------+

分组函数的执行顺序:
根据条件查询数据
分组
采用having过滤,取得正确的数据

select deptno,avg(sal) from emp where avg(sal) > 2000 group by deptno; // 错误了。
因为需要筛选的内容是带分组函数的,所以不能使用where,只能用having进行筛选。

select语句总结

select 字段
from 表名
where …….
group by ………
having …….(就是为了过滤分组后的数据而存在的—不可以单独的出现)
order by ………

以上语句的执行顺序
1.首先执行where语句过滤原始数据
2.执行group by进行分组
3.执行having对分组数据进行操作
4.执行select选出数据
5.执行order by排序
原则:能在where中过滤的数据,尽量在where中过滤,效率较高。having的过滤是专门对分组之后的数据进行过滤的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值