MySQL 知识量:16 - 40 - 165
如果只能对所有数据进行聚集计算显然不能满足要求,如果可以按某种逻辑关系进行分组,在分组中使用聚集计算就比较理想了。为了实现这个目标,就需要对数据进行分组。
要创建分组可以使用group by子句。
select age,count(*) from student group by age;
查询各年龄段的学生各有几个人。结果为:
+-----+----------+ | age | count(*) | +-----+----------+ | 10 | 2 | | 11 | 3 | | 12 | 1 | +-----+----------+
以上代码中,因为已经使用group by进行了分组,因此count()函数就对每个分组内的数据进行计数。
需要注意的几点:
group by子句可以包含任意数目的列,即可以对分组进行嵌套。
如果在group by子句中进行了嵌套,数据将在最后一个分组上进行汇总。即group by子句所有列的可能组合为一个分组。
group by 子句中的列必须是查询列或有效的表达式,但不能是聚集函数。
NULL值将作为一个分组返回,多行NULL值将分为一组。
group by子句在where子句之后,order by子句之前。
select age,sex,count(*) from student group by age,sex;
按年龄和性别统计各有几个学生。结果为:
+-----+--------+----------+ | age | sex | count(*) | +-----+--------+----------+ | 10 | male | 2 | | 11 | female | 2 | | 11 | male | 1 | | 12 | male | 1 | +-----+--------+----------+
要对分组进行进一步的过滤就要使用having子句。having子句与where子句比较相似,having子句可以使用所有where子句的操作符,但它们之间也有重要的区别。
where子句在数据分组前进行过滤。
having子句在数据分组后进行过滤。
以上的区别意味着,where子句的过滤在having子句之前,而且where子句是对行的过滤,having子句是对分组的过滤。
select age,count(*) from student group by age having count(*)>=2;
查询各年龄段的学生人数,显示2人及2人以上的年龄段信息。结果为:
+-----+----------+ | age | count(*) | +-----+----------+ | 10 | 2 | | 11 | 3 | +-----+----------+
如果要对分组数据进行排序,需要使用order by子句,注意order by子句要在最后。
select age,count(*) as total from student group by age order by total;
查询各年龄段的学生各有几个人,按人数从少到多排列。结果为:
+-----+-------+ | age | total | +-----+-------+ | 12 | 1 | | 10 | 2 | | 11 | 3 | +-----+-------+
现在有必要梳理一下select语句中各个子句的排列顺序,否则一旦出错,SQL语句将不能运行。
排序 | 子句 | 说明 | 是否必须使用 |
---|---|---|---|
1 | select | 要返回的列或表达式 | 是 |
2 | from | 从中查询数据的表 | 仅在从表查询时使用 |
3 | where | 行级过滤 | 否 |
4 | group by | 分组说明 | 仅在按组计算时使用 |
5 | having | 组级过滤 | 否 |
6 | order by | 输出排序顺序 | 否 |
7 | limit | 要查询的行数 | 否 |
全部使用以上子句排成一行:
select ... from ... where ... group by ... having ... order by ... limit ...
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6