第十三章:Mysql-GROUP BY和HAVING实现分组数据

前言

本章将介绍如何分组数据,以便能汇总表内容的子集。这涉及两个新SELECT语句子句,分别是GROUP BY子句和HAVING子句。

一、数据分组

分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算

二、创建分组

分组是在SELECT语句的GROUP BY子句中建立的。
用法:

SELECT 列名, 计算字段 FROM 表名 GROUP BY 排序分组依赖列名;

示例:

mysql> SELECT age, COUNT(*) AS num_prods FROM userinfo GROUP BY age; # GROUP BY子句指示MySQL按age排序并分组数据
+------+-----------+
| age  | num_prods |
+------+-----------+
|   18 |         2 |
|   22 |         1 |
|   24 |         1 |
|   13 |         1 |
| NULL |         1 |
+------+-----------+
5 rows in set (0.00 sec)

重要规定:

  • GROUP BY子句可以包含任意数目的列
  • 如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总
  • GROUP BY子句中列出的每个列都必须是检索列或有效的表达式
  • 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出
  • 如果分组列中具有NULL值,则NULL将作为一个分组返回
  • GROUP BY子句必须出现在WHERE子句之后ORDER BY子句之前

使用WITH ROLLUP关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值
示例:

mysql> SELECT age,  COUNT(*) AS num_prods FROM userinfo GROUP BY age WITH ROLLUP;
+------+-----------+
| age  | num_prods |
+------+-----------+
| NULL |         1 |
|   13 |         1 |
|   18 |         2 |
|   22 |         1 |
|   24 |         1 |
| NULL |         6 |
+------+-----------+
6 rows in set (0.00 sec)

三、过滤分组

所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组
用法:

SELECT 列名, 计算字段 FROM 表名 GROUP BY 排序分组依赖列名 HAVING 分组条件;

示例:

# 过滤分组中user_info = 2的组
mysql> SELECT age,COUNT(*) AS user_info FROM userinfo GROUP BY age HAVING user_info = 2;
+------+-----------+
| age  | user_info |
+------+-----------+
|   18 |         2 |
+------+-----------+
1 row in set (0.00 sec)
  • HAVING和WHERE的差别 :WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。
    示例:
mysql> SELECT age,COUNT(*) AS user_info FROM userinfo WHERE status = 0 GROUP BY age HAVING user_info = 1;
+------+-----------+
| age  | user_info |
+------+-----------+
|   18 |         1 |
|   22 |         1 |
|   24 |         1 |
|   13 |         1 |
+------+-----------+
4 rows in set (0.00 sec)

四、分组和排序

虽然GROUP BY和ORDER BY经常完成相同的工作,但它们是非常不同的。
ORDER BY 与 GROUP BY

ORDER BYGROUP BY
作用排序产生输出分组行。但输出可能不是分组的排序
限制任意列都可以使用只可能使用选择列或表达式列,而且必须使用每个选择列表达式
使用不一定需要如果与聚集函数一起使用列(或表达式),则必须使用
  • 不要忘记ORDER BY:一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证数据正确排序的唯一方法。千万不要仅依赖GROUP BY排序数据。
# 按照age进行排序
mysql> SELECT age,COUNT(*) AS user_info FROM userinfo WHERE status = 0 GROUP BY age HAVING user_info = 1 ORDER BY age;
+------+-----------+
| age  | user_info |
+------+-----------+
|   13 |         1 |
|   18 |         1 |
|   22 |         1 |
|   24 |         1 |
+------+-----------+
4 rows in set (0.01 sec)

五、SELECT子句排序

SELECT子句及其顺序

子句说明是否必须使用
SELECT要返回的列或表达式
FROM从中检索数据的表仅在从表选择数据时使用
WHERE行级过滤
GROUP BY分组说明仅在按组计算聚集时使用
HAVING组级过滤
ORDER BY输出排序顺序
LIMIT要检索的行数

小结

在第12章中,我们学习了如何用SQL聚集函数对数据进行汇总计算。本章讲授了如何使用GROUP BY子句对数据组进行这些汇总计算,返回每个组的结果。我们看到了如何使用HAVING子句过滤特定的组,还知道了ORDER BY和GROUP BY之间以及WHERE和HAVING之间的差异。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值