这是命令行操作MySQL数据库系列博客的第十七篇,今天这篇博客记录group by 与 group_concat 如何将查询结果进行分组显示。
简单分组查询
MySQL软件提供了5个统计函数来帮助用户统计数据,可以使用户很方便地对记录进行统计个数、计算和、计算平均数、计算最大值和最小值,而不需要查询所有数据。
在具体使用统计函数时,都是针对表中所有记录数或指定特定条件(WHERE子句)的数据记录进行统计计算。在现实应用中,经常会先把所有数据记录进行分组,再对这些分组后的数据记录进行统计计算。
MySQL通过SQL语句GROUP BY来实现,分组数据查询语法如下:select 函数名(字段名), 函数名(字段名), ..., [字段名] from 表名 [where 条件] group by 字段名;
可写多个函数同时计算,如下面例5。
where条件可有可无!
加上[字段名]是为了显示该行的提示作用,可有可无!
在上述语句中,参数表示某字段名,通过该字段对表的数据记录进行分组。
注意:在具体进行分组查询时,分组所依据的字段上的值一定要具有重复值,否则分组没有任何意义。(也就是group by 后面的字段名必须是要有重复值)
例:
首先创建表,并插入数据
create table group_by(id int PRIMARY KEY, name varchar(128), math int, chinese int, english int, class_id int);
insert into group_by value(1, '甲', 78, 88, 98, 1), (2, '乙', 67, 77, 87, 2), (3, '丙', 89, 99, 100, 1), (4, '丁', NULL, 66, 76, 2);
五个统计函数简介
- 统计数量 COUNT
COUNT(*):该种方式可以实现对表中记录进行统计,不管表字段中包含的是NULL值还是非NULL值。
例:
select COUNT(*), class_id from group_by group by class_id;
COUNT(field):该种方式可以实现对指定字段的记录进行统计,在具体统计时将忽略NULL值。
例:
select COUNT(math), class_id from group_by group by class_id;
经过前后对比可以发现,使用COUNT( * )函数,即使数据中有NULL值,也会进行统计,但使用COUNT(字段名)函数,就不统计函数NULL值的项。
- 统计计算平均值 AVG
该函数只有一种使用方式。
AVG(字段名)使用方式:该种方式可以实现对指定字段的平均值进行计算,在具体统计时将忽略NULL值。
也就是说,哪一个字段为NULL,该字段将不作为统计项,例如下面例子中,2班的丁同学的数学成绩为NULL,乙同学数学成绩为67,所以统计2班的数学平均分为67分。
例:统计每个班的全部成绩平均值:
select AVG(math), AVG(chinese), AVG(english), class_id from group_by group by class_id;
- 统计计算求和 SUM
该函数只有一种使用方式。
SUM(字段名)使用方式:该种方式可以实现计算指定字段值之和,在具体统计时将忽略NULL值。
例:统计每班的数学总分
select SUM(math), class_id from group_by group by class_id;
- 统计最大值 MAX
该函数只有一种使用方式。
MAX(字段名)使用方式:该种方式可以实现计算指定字段值中的最大值,在具体统计时将忽略NULL值。
例:统计语文成绩的最大值和最小值
select MAX(chinese), MIN(chinese), class_id from group_by group by class_id;
- 统计最小值 MIN
该函数只有一种使用方式。
MIN(field)使用方式:该种方式可以实现计算指定字段值中的最小值,在具体统计时将忽略NULL值。
例:将全部函数全部一起使用
select COUNT(*), AVG(chinese), SUM(english), MAX(english), MIN(english), class_id from group_by group by class_id;
统计分组查询
在MySQL中,只实现简单的分组查询有时候可能没有任何实际意义,因为关键字GROUP BY单独使用时,默认查询出每个分组中随机的一条记录,具有很大的不确定性,一般建议将分组关键字与统计函数一起使用。
例如:查询表中每组的个数,并显示所在组的成员名字
select class_id, COUNT(*), name from group_by group by class_id;
可以看到,1,2班都有两名同学,却只显示一个同学的名字,这是不合理的,为了显示所有同学的名字,得使用GROUP_CONCAT。
如果想显示每个分组中的字段,可以通过函数GROUP_CONCAT()来实现。该函数可以实现显示每个分组中的指定字段,函数的具体语法形式如下:
select [字段名], 函数名(字段名或*), GROUP_CONCAT(字段名) from 表名 [where 条件] group by 字段名;
[字段名]可有可无,任意函数都可以,条件可有可无!
例:
使用GROUP_CONCAT进行分组,将分组后的班级显示所有班级学生名字。
select class_id, COUNT(*), GROUP_CONCAT(name) from group_by where class_id > 0 group by class_id;
总结:
group by对查询结果进行分组显示,值得注意的是,查询的数据必须要有相同值的字段,否则分组查询将毫无意义。如果需要显示其他字段存储的全部数据,则需要配合group_concat一起使用。