文章目录

  • ​​准备`sql`​​
  • ​​执行​​
  • ​​分析执行过程​​

用了很久的​​gorup by​​​一道面试题让我突然觉得自己不会用了。原题是这样的:表A有三个列分别为​​a、b、c​​​。语句​​select a,b,c from A group by 【a、b、c任意一个字段】​​会出现什么情况。

答案是这样的,不管你是以​​a、b、c​​​哪一个字段来分组,第一条件:分组的依据要么包含在​​select​​后面要么就是聚合函数包含(必须保证分组之后显示的字段是唯一的,含有多个的情况就必须进行聚合)。还有一种情况就是查询结果集只有分组的依据(没有意义)。

# 伪代码表示
(select 包含分组条件 || 聚合函数包含分组条件|| 只查询分组条件进行分组(没有意义)|| 以主键ID进行分组(没有意义))&& 查询显示的结果字段唯一(不能含有多个值)

# 总结: 分组之后的结果有多个的话必须进行聚合

准备​​sql​

drop table if exists `test`;
create table if not exists `test`(
`id` bigint not null auto_increment comment '主键ID',
`name` varchar(10) not null comment '名称',
`count` bigint not null default 10 comment '次数',
primary key (`id`)
)engine=innodb auto_increment = 66 default charset=utf8 comment '测试表';


insert into `test` (`name`,`count`) values ("a",59),
("a",44),
("a",55534),
("b",22),
("c",95468),
("d",66),
("d",43),
("d",76);

执行

-- 不管name是否重复都可以执行但是没有意义
select `name` from `test` group by `name`

-- 都是可以执行的,以主键分组有什么意义呢
select `id`,`count` from `test` group by `id`
select `id`,`name` from `test` group by `id`
select `id`,`name`,`count` from `test` group by `id`

-- 不管name是否唯一都不能执行(name分组之后会有多个结果集需要进行汇聚)
select `id`,`name`,`count` from `test` group by `name`

-- 可以执行
select sum(`id`),`name`,sum(`count`) from `test` group by `name`

-- 不管count是否唯一都不能执行
select `id`,`name`,`count` from `test` group by `count`

-- 可以执行没有意义
select `id`,`name`,`count` from `test` group by `count`,`id`

-- 正确用法
select `name`,sum(`count`) as `count` from `test` group by `name`;

分析执行过程

关于group by的用法_字段

为了更好的理解​​group by​​多个列和聚合函数的应用,将从表1到表3的过程模拟出一张中间表表2。

关于group by的用法_mysql_02

最终返回的结果为表2,但是此时​​id​​​和​​count​​​单元格内是有多个值的。我们都知道关系型数据库是不允许一个单元格内存在多个值的。所以当分组之后返回的结果单元格中含有多个值是就出错了。比如说​​select *​​。

对于这种含有一个单元格内含有多个值的解决方式就是聚合,把这些多个单元格值聚合为一个,就能正确执行了。