Skip to content
On this page

分组查询

分组查询

查询表中分组列的信息,比如每个学科的平均成绩

sql
mysql> select subject, avg(score) from student_score group by subject;
+-----------------------------+------------+
| subject                     | avg(score) |
+-----------------------------+------------+
| 母猪的产后护理              |    73.0000 |
| 论萨达姆的战争准备          |    73.2500 |
+-----------------------------+------------+
2 rows in set (2.41 sec)

mysql>

where 子查询

去掉一个最低分,去掉一个最高分

sql
mysql> select subject,avg(score) from student_score where score >= 90 or score <= 50 group by subject;
+-----------------------------+------------+
| subject                     | avg(score) |
+-----------------------------+------------+
| 母猪的产后护理              |   100.0000 |
| 论萨达姆的战争准备          |    72.0000 |
+-----------------------------+------------+
2 rows in set (0.00 sec)

mysql>

过滤条件

只查询想查询的条件,关键词 having。比方说老师想要查询平均分大于73分的课程

sql
mysql> select subject, avg(score) from student_score group by subject having avg(score) >70;
+-----------------------------+------------+
| subject                     | avg(score) |
+-----------------------------+------------+
| 母猪的产后护理              |    73.0000 |
| 论萨达姆的战争准备          |    73.2500 |
+-----------------------------+------------+
2 rows in set (0.00 sec)

mysql>

想查询最高分大于98分的课程的平均分

sql
mysql> select subject, avg(score) from student_score group by subject having max(score) > 98;
+-----------------------+------------+
| subject               | avg(score) |
+-----------------------+------------+
| 母猪的产后护理        |    73.0000 |
+-----------------------+------------+
1 row in set (0.00 sec)

mysql>

分组排序

想按照各个学科的平均分从大到小降序排序

sql
mysql> select subject, avg(score) as avg_score from student_score group by subject order by avg_score desc;
+-----------------------------+-----------+
| subject                     | avg_score |
+-----------------------------+-----------+
| 论萨达姆的战争准备          |   73.2500 |
| 母猪的产后护理              |   73.0000 |
+-----------------------------+-----------+
2 rows in set (0.00 sec)

mysql>

嵌套分组

分组里面嵌套分组

sql
mysql> select department,major,count(*) from student_info group by department, major;
+-----------------+--------------------------+----------+
| department      | major                    | count(*) |
+-----------------+--------------------------+----------+
| 计算机学院      | 计算机科学与工程         |        2 |
| 计算机学院      | 软件工程                 |        2 |
| 航天学院        | 飞行器设计               |        1 |
| 航天学院        | 电子信息                 |        1 |
+-----------------+--------------------------+----------+
4 rows in set (2.37 sec)

mysql>

image.png

分组注意事项

  • 如果分组列中有 null 值,null 也会作为一个独立的分组
  • 如果存在嵌套分组,聚焦函数会作用于最后一个分组列
  • 如果同时出现 where 子句,group by 子句 order by 子句,group by 必须出现在where 后,order by
  • 非分组列不能单独出现在检索列表中(可以被放到聚集函数中)
  • GROUP BY 子句后也可以跟随表达式(但不能是聚集函数)。
sql
mysql> select concat("专业:", major), count(*) from student_info group by concat("专业:", major);
+---------------------------------+----------+
| concat("专业:", major)          | count(*) |
+---------------------------------+----------+
| 专业:计算机科学与工程           |        2 |
| 专业:软件工程                   |        2 |
| 专业:飞行器设计                 |        1 |
| 专业:电子信息                   |        1 |
+---------------------------------+----------+
4 rows in set (0.00 sec)

mysql>
  • WHERE 子句和 HAVING 子句的区别。
    • WHERE 子句在分组前进行过滤,作用于每一条记录,WHERE 子句过滤掉的记录将不包括在分组中
    • HAVING子句在数据分组后进行过滤,作用于整个分组。

简单查询语句中各子句的顺序

sql
SELECT [DISTINCT] 查询列表
[FROM 表名]
[WHERE 布尔表达式]
[GROUP BY 分组列表 ]
[HAVING 分组过滤条件]
[ORDER BY 排序列表]
[LIMIT 开始行, 限制条数]