环境
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处于严格模式(sql_mode被设置为ONLY_FULL_GROUP_BY),
这时,如果SQL写成select * from t group by name
,就会报错,原因就是因为除了name之前,其他列的数据都不是唯一的,在严格模式会报错。
不过,在严格模式(ONLY_FULL_GROUP_BY
)下,依然是想获取聚合列:
- 方法一:使用
ANY_VALUE(非聚合列)
进行查询,ANY_VALUE参考文档,
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),多字段分组查询