
mysql> show create table student_infoG
*************************** 1. row ***************************
Table: student_info
Create Table: CREATE TABLE `student_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '姓名',
`score` int(11) DEFAULT NULL COMMENT '分数',
`class` varchar(20) DEFAULT NULL COMMENT '班级',
`campus` varchar(128) DEFAULT NULL COMMENT '校区',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COMMENT='学生基本信息表'
1 row in set (0.01 sec)
mysql> select * from student_info;
+----+-------+-------+--------+-----------+
| id | name | score | class | campus |
+----+-------+-------+--------+-----------+
| 1 | stu1 | 100 | 一班 | 南校区 |
| 2 | stu2 | 85 | 一班 | 南校区 |
| 3 | stu3 | 70 | 二班 | 南校区 |
| 4 | stu4 | 50 | 一班 | 南校区 |
| 5 | stu5 | 88 | 二班 | 南校区 |
| 6 | stu6 | 86 | 三班 | 北校区 |
| 7 | stu7 | 90 | 三班 | 北校区 |
| 8 | stu8 | 50 | 一班 | 南校区 |
| 9 | stu9 | 98 | 二班 | 南校区 |
| 10 | stu10 | 92 | 三班 | 西校区 |
+----+-------+-------+--------+-----------+
10 rows in set (0.00 sec)
mysql> SELECT AVG(score) FROM student_info where class='一班';
+------------+
| AVG(score) |
+------------+
| 71.2500 |
+------------+
1 row in set (0.00 sec)
mysql> SELECT AVG(score) FROM student_info where class='二班';
+------------+
| AVG(score) |
+------------+
| 85.3333 |
+------------+
1 row in set (0.00 sec)
mysql> SELECT AVG(score) FROM student_info where class='三班';
+------------+
| AVG(score) |
+------------+
| 89.3333 |
+------------+
1 row in set (0.00 sec)

一、分组

mysql> SELECT AVG(score),class FROM student_info group by class;
+------------+--------+
| AVG(score) | class |
+------------+--------+
| 71.2500 | 一班 |
| 89.3333 | 三班 |
| 85.3333 | 二班 |
+------------+--------+
3 rows in set (0.00 sec)
mysql> SELECT AVG(score),class,name FROM student_info group by class;
ERROR 1055 (42000): Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test_mysql.student_info.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

二、分组和筛选
mysql> SELECT AVG(score),class FROM student_info group by class where AVG(score)>=80;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where AVG(score)>=80' at line 1
mysql> SELECT AVG(score),class FROM student_info group by class having AVG(score)>=80;
+------------+--------+
| AVG(score) | class |
+------------+--------+
| 89.3333 | 三班 |
| 85.3333 | 二班 |
+------------+--------+
2 rows in set (0.01 sec)
mysql> SELECT AVG(score),class FROM student_info where score >= 60 group by class;
+------------+--------+
| AVG(score) | class |
+------------+--------+
| 92.5000 | 一班 |
| 89.3333 | 三班 |
| 85.3333 | 二班 |
+------------+--------+
3 rows in set (0.00 sec)
mysql> SELECT AVG(score),class FROM student_info where score >= 60 group by class having AVG(score)>90;
+------------+--------+
| AVG(score) | class |
+------------+--------+
| 92.5000 | 一班 |
+------------+--------+
1 row in set (0.01 sec)
mysql> SELECT AVG(score),class FROM student_info where score >= 60 group by class having MAX(score)>95;
+------------+--------+
| AVG(score) | class |
+------------+--------+
| 92.5000 | 一班 |
| 85.3333 | 二班 |
+------------+--------+
2 rows in set (0.01 sec)

三、分组与排序
mysql> SELECT AVG(score) as avg_score,class FROM student_info group by class having AVG(score)>=80 order by avg_score desc;
+-----------+--------+
| avg_score | class |
+-----------+--------+
| 89.3333 | 三班 |
| 85.3333 | 二班 |
+-----------+--------+
2 rows in set (0.00 sec)
mysql> SELECT AVG(score) as avg_score,class FROM student_info group by class having AVG(score)>=80 order by avg_score desc limit 1;
+-----------+--------+
| avg_score | class |
+-----------+--------+
| 89.3333 | 三班 |
+-----------+--------+
1 row in set (0.00 sec)

四、嵌套分组
mysql> SELECT AVG(score),campus FROM student_info group by campus;
+------------+-----------+
| AVG(score) | campus |
+------------+-----------+
| 88.0000 | 北校区 |
| 77.2857 | 南校区 |
| 92.0000 | 西校区 |
+------------+-----------+
3 rows in set (0.00 sec)
mysql> SELECT AVG(score),campus,class FROM student_info group by campus,class;
+------------+-----------+--------+
| AVG(score) | campus | class |
+------------+-----------+--------+
| 88.0000 | 北校区 | 三班 |
| 71.2500 | 南校区 | 一班 |
| 85.3333 | 南校区 | 二班 |
| 92.0000 | 西校区 | 三班 |
+------------+-----------+--------+
4 rows in set (0.01 sec)

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

六、总结
-
如果分组列中含有NULL值,那么NULL也会作为一个独立的分组存在。 -
非分组列不能单独出现在检索列表中(可以被放到聚集函数中)。 -
WHERE子句和HAVING子句的区别:WHERE子句在分组前进行过滤,作用于每一条记录,WHERE子句过滤掉的记录将不包括在分组中。而HAVING子句在数据分组后进行过滤,作用于整个分组。 -
如果存在多个分组列,也就是嵌套分组,即按照多个列进行分组。 -
各子句的顺序不能乱放,请务必熟记于心!
原文始发于微信公众号(幕后哈土奇):12|第十二话:基础篇-MySQL之分组查询
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112828.html