分组查询
分组查询
查询表中分组列的信息,比如每个学科的平均成绩
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>
分组注意事项
- 如果分组列中有 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 开始行, 限制条数]