环境

mysql : 5.7.26-log

前言

笔记,非教程;
最近做的需求,需要用到group by,刚好发现自己有点陌生,所以做个笔记;
看到网上资料说:

# 这种写法会报错,但是我在实践中发现不会报错;所以简单研究了
# MySQL如果开启了严格模式(sql_model=ONLY_FULL_GROUP_BY)才会报错
select * ... group by ...语句

group by

分组函数一般都会和group by联合使用!这也是为什么它被称为分组函数的原因。

任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的!

任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的!

任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的!

当一条sql语句没有group by,整张表的数据会自成一组。

下列图表,假设我们对name进行分组,分组后可以想象中得到虚拟表3.

mysql 怎么关闭严格模式 mysql严格模式group by_mysql

如果MySQL处于严格模式(sql_mode被设置为ONLY_FULL_GROUP_BY),
这时,如果SQL写成select * from t group by name,就会报错,原因就是因为除了name之前,其他列的数据都不是唯一的,在严格模式会报错。

不过,在严格模式(ONLY_FULL_GROUP_BY)下,依然是想获取聚合列:

SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;

原理就是从分组中,随意获取一个数据,前提也就是你不关心组数据中的不同情况。

  • 方法二:如果GROUP BY是主键或者 unique NOT NULL 时是可以查询非聚合的列的,原因是此时分组的key是主键,则每一个分组只有一条数据,因此是可以进行查询非聚合的列的。
  • 方法三:关闭严格模式
    查看当前sql_model:

查看当前sql_model

SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

总结

在非严格模式下,使用group by后,可以在select 非聚合列(也就是没有出现group by后面的字段),这是获取的非聚合列,是自然顺序的第一条;
在严格模式下,使用group by 后,不可以select 非聚合列,解决方法有三种:

  • any_value(字段名)
  • group by 字段是主键或者非空唯一键
  • 关闭严格模式

参考地址

这个是通俗易懂类型:
Group by分组详解

MySQL中的Group By是否允许SELECT非聚合列的总结

【MySQL】十一、分组函数(group by,having),多字段分组查询