事情起因:
使用mysql存储im消息,需要从消息表中读取会话列表返回给客户端,介于此需求理所当然的想到了group by(有其它想法的望留言告知~~:),所以当我写出了如下sql语句时,出人意料的爆出了only_full_group_by错误:
select conversationid,content,create_time
from (
select peerid as conversationid,content,create_time from demo.msg where uid = 100 and peerid <> 100
union
select uid as conversationid,content,create_time from demo.msg where uid <> 100 and peerid = 100
order by
create_time desc)as tableother group by conversationid;
Error Code: 1055. Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'newtable.content' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
经过
正所谓出了问题逃避不是解决的办法,出了问题总归要有人承担责任的,于是赶紧先google了一番~~,
经过搜索归纳得出了以下几点不成熟的分析:
- only_full_group_by规则类似于oracle的group,select查询列需要在group里面,或者本身是函数
- MySQL5.7.5之前的版本没有对功能依赖的检测,所以不会出现此问题
- MySQL5.7.5及更高版本默认开启了only_full_group_by模式,如果不遵守第一条规定则出现此错误(配置查询:select @@sql_mode;)
解决
- 修改配置文件
$ vim /usr/local/etc/my.cnf
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
- SQL命令
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
- 通过ANY_VALUE(推荐)
贴一下MySQL官网的案例解说:
ANY_VALUE
This function is useful forGROUP BY
queries when theONLY_FULL_GROUP_BY
SQL mode is enabled, for cases when MySQL rejects a query that you know is valid for reasons that MySQL cannot determine. The function return value and type are the same as the return value and type of its argument, but the function result is not checked for theONLY_FULL_GROUP_BY
SQL mode.
For example, ifname
is a nonindexed column, the following query fails withONLY_FULL_GROUP_BY
enabled:
mysql> SELECT name, address, MAX(age) FROM t GROUP BY name;
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP
BY clause and contains nonaggregated column 'mydb.t.address' which
is not functionally dependent on columns in GROUP BY clause; this
is incompatible with sql_mode=only_full_group_by
The failure occurs because address
is a nonaggregated column that is neither named among GROUP BY
columns nor functionally dependent on them. As a result, the address
value for rows within each name
group is nondeterministic. There are multiple ways to cause MySQL to accept the query:
-
Alter the table to make
name
a primary key or a uniqueNOT NULL
column. This enables MySQL to determine thataddress
is functionally dependent onname
; that is,address
is uniquely determined byname
. (This technique is inapplicable ifNULL
must be permitted as a validname
value.) -
Use
ANY_VALUE()
to refer toaddress
:
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
结果
所以最终的sql语句为:
select conversationid,any_value(content) as content,any_value(create_time) as create_time
from (
select peerid as conversationid,content,create_time from demo.msg where uid = 100 and peerid <> 100
union
select uid as conversationid,content,create_time from demo.msg where uid <> 100 and peerid = 100
order by
create_time desc)as tableother group by conversationid;
本篇文章参考:
https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
https://blog.csdn.net/MissWwg/article/details/77719085
https://blog.csdn.net/loveliness_peri/article/details/88051316
https://www.cnblogs.com/ttrrpp/p/12724603.html
网友评论