赞
赏
前面的章节中,我们的数据查询都是针对特定的数据或者表里面的所有数据。但是如果遇到需要分组的数据,我们该怎么办呢?这个时候,我们就可以使用分组语句了,group by 语句。
本章节我们使用下面的表里面的语句进行操作
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`stu_no` int(11) DEFAULT NULL,
`stu_name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`class_id` int(11) NOT NULL COMMENT '班级ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;
INSERT INTO `student` VALUES (1, 1001, 'xiaoming', 17, 1);
INSERT INTO `student` VALUES (2, 1002, 'honghong', 16, 2);
INSERT INTO `student` VALUES (3, 1003, 'xiaojun ', 18, 3);
INSERT INTO `student` VALUES (4, 1004, '小亮', 19, 1);
INSERT INTO `student` VALUES (5, 1005, 'LIANGLIANG', 19, 2);
INSERT INTO `student` VALUES (6, 1006, ' 小 杰 ', 16, 3);
INSERT INTO `student` VALUES (7, 1007, '小亮', NULL, 1);
INSERT INTO `student` VALUES (8, 1008, '无年龄', NULL, 2);
INSERT INTO `student` VALUES (9, 1009, '欧阳亮亮', 19, 3);
GROUPBY详解
语法
SELECT 列1,列2... FROM 表名 GROUP BY 列名
详解
- GROUP BY 的子句可以包含任意多个列,它会将所有的列都一起计算。
- GROUP BY 一般和 聚集函数[数据汇总] 一起使用,一般求一些分组后的数据里面的某个具体的值。
- 如果分列的数据中含有 null,那么它会将 null 作为一个分组返回。如果有多行为 null 的值,它会返回一组。
- GROUP BY 语句必须出现在 WHERE 子句的后面,出现在 ORDER BY 子句的前面。
案例
SELECT count(1) from student group by class_id;
运行结果如下
![42 group_by_02.png](/uploads/pic/database/mysql/mysql-select/42 group_by_02.png)
上面的例子就是根据 class_id 来统计每个班有多少学生。通过 group by 来将班级分组,然后使用 count[聚集函数] 聚合函数来统计每个班级里面的学生数量信息。它统计出每个班级的学生数量都是 3 个。
-- 嗨客网(www.haicoder.net)
select count(1),class_id from student where stu_name like '%亮%' group by class_id;
运行结果如下
![43 group_by_03.png](/uploads/pic/database/mysql/mysql-select/43 group_by_03.png)
我们使用 where 条件,将每个班里面,名字中含有 亮
字的学生数量统计列出来。group by 子句必须放在 where 条件后面。
过滤分组
我们都知道,通过 where 语句,可以对查询结果里面的数据进行过滤,查询出指定条件的数据,但是我们也可以对分组的数据进行过滤,它需要使用 HAVING 关键字,该关键字是对 GROUP BY 语句查询到的结果进行过滤。
语法
SELECT 列1,列2... FROM 表名 GROUP BY 列名 HAVING 条件语句;
详解
有些同学看到这边,可能犯嘀咕了,为啥有了 where 之后还需要有 having 呢?where 是在数据分组前对数据进行过滤,而 having 是在数据分组后对组数据进行过滤。经过 where 过滤后的数据不会在分组中出现。
案例
-- 嗨客网(www.haicoder.net)
select class_id,count(1) from student where stu_name like '%亮%' group by class_id
HAVING COUNT(1) >= 2;
运行结果如下
![44 group_by_04.png](/uploads/pic/database/mysql/mysql-select/44 group_by_04.png)
上面的例子是我们根据班级对学生的信息进行分组,前提是学生的姓名中包含亮。然后将班级里面名字里面含有亮字的学生数量大于等于 2 的班级 ID 信息列出来。
分组排序
其实从上面的例子中我们可以感受到,对数据进行分组后,每个组只会有一条数据,前面我们讲过 数据的排序[mysql 排序查询],它是针对查询到的结果进行排序,那么对分组后对数据呢?我们也可以进行排序。