group by平时用的少,每隔一段时间就忘记了。导致每次都要来回顾。其实归根结底就是没有好好理解group by。
先建一个student 表 ,还有插入一些数据。
create table student(
id int auto_increment primary key comment 'id',
name VARCHAR(30) comment '学生姓名',
grade varchar(10) comment '等级',
mark int comment '分数',
index indexName(name)
)engine=InnoDB default charset = utf8;
insert into student(name, grade, mark)
values ('张1','A',100),('张2','B',100),
('张3','C',100),('张4','C',100),('张1','A',100);
一个字段的分组
先来个简单的,大家都能理解的,也就是把相同名字的人,分数加在一起。
select sum(mark),name from student group by name;
注意事项。
group by 字段 中的字段只能是select 需要查询中的字段。或者是聚合函数(任意字段)。
比如下面这句话:就会报错
[42000][1055] Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'demo.student.grade' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
select sum(mark),name ,grade from student group by name;
大概意思就是,grade这个字段,group by 没有用到,所以select中不能查询。
但是如果你换成查询聚合函数,就没有问题。比如:就不会报错。
select sum(mark),name ,count(grade) from student group by name;
多个字段的分组
搞懂了上面。现在我们来进行 group by 字段1 字段2。。。 多个字段进行分组。
select sum(mark),name ,grade from student group by name ,grade;
其实道理跟只有一个字段分组是一模一样的。 多个字段进行分组时,需要将name和grade看成一个整体,只要是name和grade相同的可以分成一组;如果只是name相同,grade不同就不是一组。
若须引入聚合函数来对group by 结果进行过滤 则只能用having。
正确 select sum(mark),name ,grade from student group by name ,grade Having sum(student.id)>2;
错误 select sum(mark),name ,grade from student group by name ,grade where sum(student.id)>2;
总结:只有一个字段分组,就按照那个字段进行分组。 多个字段进行分组时,需所有字段都符合才为一组。 select查询的字段得group by 分组字段 中存在才能查询。 或者查询聚合函数就不用。