浅谈MySQL中的group by
作者:李子捌 发布时间:2024-01-18 22:53:54
目录
1、前言
2、准备user表
2.1 group by规则
2.2 group by使用
2.3 having使用
2.4 order by与limit
2.5 with rollup
1、前言
MySQL
的group by
用于对查询的数据进行分组;此外MySQL
提供having
子句对分组内的数据进行过滤。
MySQL
提供了许多select
子句关键字,
它们在语句中的顺序如下所示:
子句 | 作用 | 是否必须/何时使用 |
---|---|---|
select | 查询要返回的数据或者表达式 | 是 |
from | 指定查询的表 | 否 |
where | 指定行级过滤 | 否 |
group by | 分组 | 否/对数据分组时使用 |
having | 分组过滤 | 否/对分组后的数据过滤使用 |
order by | 返回数据时指定排序规则 | 否 |
limit | 指定返回数据的行数 | 否 |
2、准备user表
准备一张user表,其DDL和表数据如下所示
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
`nation` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '民族',
`age` int(11) NULL DEFAULT NULL COMMENT '年龄',
`height` double NULL DEFAULT NULL COMMENT '身高',
`sex` smallint(6) NULL DEFAULT NULL COMMENT '性别',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '李子捌', '汉族', 18, 180, 1);
INSERT INTO `user` VALUES (2, '张三', '回族', 20, 175, 1);
INSERT INTO `user` VALUES (3, '李四', ' * 尔族', 45, 168, 0);
INSERT INTO `user` VALUES (4, '王五', '蒙古族', 18, 177, 1);
INSERT INTO `user` VALUES (5, '赵六', '汉族', 16, 184, 0);
INSERT INTO `user` VALUES (6, '田七', ' * 尔族', 27, 192, 1);
user表中数据如下所示:
mysql> select * from user;
+----+--------+----------+------+--------+------+
| id | name | nation | age | height | sex |
+----+--------+----------+------+--------+------+
| 1 | 李子捌 | 汉族 | 18 | 180 | 1 |
| 2 | 张三 | 回族 | 20 | 175 | 1 |
| 3 | 李四 | * 尔族 | 45 | 168 | 0 |
| 4 | 王五 | 蒙古族 | 18 | 177 | 1 |
| 5 | 赵六 | 汉族 | 16 | 184 | 0 |
| 6 | 田七 | * 尔族 | 27 | 192 | 1 |
+----+--------+----------+------+--------+------+
6 rows in set (0.00 sec)
2.1 group by规则
使用group by
之前需要先了解group by
使用的相关规则
group by
子句置于where
之后,order by
子句之前having
子句置于group by 之后,order by子句之前group by
子句中的每个列都必须是select的检索列或者有效表达式,不能使用聚集函数select
中使用的表达式,在group by子句中必须出现,并且不能使用别名group by
分组的数据中包含null值,null值被分为一组group by
子句可以嵌套,嵌套的分组在最后分组上汇总
2.2 group by使用
需求:
统计不同民族的用户数
语句:
mysql> select nation, count(*) from user group by nation;
+----------+----------+
| nation | count(*) |
+----------+----------+
| 汉族 | 2 |
| 回族 | 1 |
| * 尔族 | 2 |
| 蒙古族 | 1 |
+----------+----------+
4 rows in set (0.00 sec)
group by可以结合where
一起使用,不过where
不能在group by
之后进行过滤,使用where
子句之后,分组的数据是where子句过滤后的数据集。
mysql> select nation, count(*) as nation_num from user where sex = 0 group by nation;
+----------+------------+
| nation | nation_num |
+----------+------------+
| * 尔族 | 1 |
| 汉族 | 1 |
+----------+------------+
2 rows in set (0.00 sec)
2.3 having使用
对group by
分组后的数据还需要再次过滤,就必须使用having
子句。group by
子句后使用where子句MySQL服务器会抛出异常
mysql> select nation, count(*) as nation_num from user group by nation where nation = '汉族';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where nation = '汉族'' at line 1
此时只需要将上面where子句替换成having子句即可,having
子句支持所有的where
操作符,通俗的说where子句能用的地方只有替换成having
就可以在group by
子句后使用了
vmysql> select nation, count(*) as nation_num from user group by nation having nation = '汉族';
+--------+------------+
| nation | nation_num |
+--------+------------+
| 汉族 | 2 |
+--------+------------+
1 row in set (0.00 sec)
2.4 order by与limit
分组后的数据需要排序可以使用order by
,order by
子句需要更在having
子句之后。
mysql> select nation, count(*) as nation_num from user group by nation having nation != '汉族' order by nation_num desc;
+----------+------------+
| nation | nation_num |
+----------+------------+
| * 尔族 | 2 |
| 回族 | 1 |
| 蒙古族 | 1 |
+----------+------------+
3 rows in set (0.00 sec)
对于输出的结果需要指定返回的行数,可以使用limit
,limit子句在整个语句的最后。
mysql> select nation, count(*) as nation_num from user group by nation having nation != '汉族' order by nation_num desc limit 2;
+----------+------------+
| nation | nation_num |
+----------+------------+
| * 尔族 | 2 |
| 回族 | 1 |
+----------+------------+
2 rows in set (0.00 sec)
2.5 with rollup
在group by子句中,WITH ROLLUP
可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)
比如max():
mysql> select nation, max(height) as nation_num from user group by nation with rollup;
+----------+------------+
| nation | nation_num |
+----------+------------+
| 回族 | 175 |
| 汉族 | 184 |
| * 尔族 | 192 |
| 蒙古族 | 177 |
| NULL | 192 |
+----------+------------+
5 rows in set (0.00 sec)
比如avg():
mysql> select nation, avg(height) as nation_num from user group by nation with rollup;
+----------+--------------------+
| nation | nation_num |
+----------+--------------------+
| 回族 | 175 |
| 汉族 | 182 |
| * 尔族 | 180 |
| 蒙古族 | 177 |
| NULL | 179.33333333333334 |
+----------+--------------------+
5 rows in set (0.00 sec)
比如count():
mysql> select nation, count(*) as nation_num from user group by nation with rollup;
+----------+------------+
| nation | nation_num |
+----------+------------+
| 回族 | 1 |
| 汉族 | 2 |
| * 尔族 | 2 |
| 蒙古族 | 1 |
| NULL | 6 |
+----------+------------+
5 rows in set (0.00 sec)
来源:https://juejin.cn/post/7032079581802201124


猜你喜欢
- 循环用于重复执行一些程序块。从上一讲的选择结构,我们已经看到了如何用缩进来表示程序块的隶属关系。循环也会用到类似的写法。for循环for循环
- 1引言实现磁带备份数据的功能有两方面的困难:首先,SQL Server(以下简称SQL)所提供的数据库的整体备份及恢复功能不能直接满足本系统
- 前言多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有
- 前言什么是OCR?光学字符识别(Optical Character Recognition, OCR),是指对文本资料的图像文件进行分析识别
- Python异步编程之Asyncio1. 协程简介1.1 协程的含义及实现方法协程(Coroutine),也可以被称为微线程,是一种用户态内
- 以下几种方法来模拟enum:(感觉方法一简单实用)# way1class Directions: up
- 本文实例讲述了Python列表推导式、字典推导式与集合推导式用法。分享给大家供大家参考,具体如下:推导式comprehensions(又称解
- 本文实例为大家分享了Python实现学生管理系统的具体代码,供大家参考,具体内容如下实现从面向过程到面向对象的过度,通过更改前面的学生管理系
- 前言: 上一篇讲了Python排序问题中比较经典的三个方法,(链接:关于Python排
- OCR简介OCR,即Optical Character Recognition,光学字符识别,是指通过扫描字符,然后通过其形状将其翻译成电子
- 一、yield运行方式我们定义一个如下的生成器:def put_on(name): print("Hi {}, 货物来了,准备搬到
- Eloquent: 关联模型简介数据库中的表经常性的关联其它的表。比如,一个博客文章可以有很多的评论,或者一个订单会关联一个用户。Eloqu
- 前言使用PyCharm在Python Interpreter设置中的Python虚拟环境安装第三方包时,很有可能报错:Non-zero ex
- 本文实例讲述了Oracle删除死锁进程的方法。分享给大家供大家参考。具体如下:步骤1:用以下SQL查看进程列表,判断出被锁定的表SELECT
- 随笔:(1) 命名空间  
- 1.后台action产生json数据。List blackList = blackService.getBlackInfoList(mobi
- 今天用FrontPage2003,无意中发现一个bug,稍加研究,基本发现这个bug的规律了首先是我的系统版本和Frontpage版本:我的
- 源代码、参数及其意义:def sub(pattern, repl, string, count=0, flags=0): &n
- 这段时间,关于asp的前途,关于asp的好坏的讨论贴,都有好些了。当然,大家的心都是好的,但是一些朋友说的话,真是让人郁闷。个人觉得,在现在
- 今天我们来使用Python实现递归算法求指定位数的斐波那契数列首先我们得知道斐波那契数列是什么?斐波那契数列又叫兔子数列斐波那契数列就是一个