MySQL

MySQL 知识量:16 - 40 - 165

5.4 分组数据><

创建分组- 5.4.1 -

如果只能对所有数据进行聚集计算显然不能满足要求,如果可以按某种逻辑关系进行分组,在分组中使用聚集计算就比较理想了。为了实现这个目标,就需要对数据进行分组。

要创建分组可以使用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 |
+-----+--------+----------+

过滤分组- 5.4.2 -

要对分组进行进一步的过滤就要使用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 |
+-----+----------+

分组和排序- 5.4.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 |
+-----+-------+

子句的顺序- 5.4.4 -

现在有必要梳理一下select语句中各个子句的排列顺序,否则一旦出错,SQL语句将不能运行。

排序子句说明是否必须使用
1select要返回的列或表达式
2from从中查询数据的表仅在从表查询时使用
3where行级过滤
4group by分组说明仅在按组计算时使用
5having组级过滤
6order by输出排序顺序
7
limit要查询的行数

全部使用以上子句排成一行:

select ... from ... where ... group by ... having ... order by ... limit ...