记一次获取会话列表与sql_mode=only_full_group_by错误

事情起因:

使用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了一番~~,
经过搜索归纳得出了以下几点不成熟的分析:

  1. only_full_group_by规则类似于oracle的group,select查询列需要在group里面,或者本身是函数
  2. MySQL5.7.5之前的版本没有对功能依赖的检测,所以不会出现此问题
  3. MySQL5.7.5及更高版本默认开启了only_full_group_by模式,如果不遵守第一条规定则出现此错误(配置查询:select @@sql_mode;)

解决

  1. 修改配置文件
$ 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
  1. SQL命令
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
  1. 通过ANY_VALUE(推荐)
    贴一下MySQL官网的案例解说:
    ANY_VALUE
    This function is useful for GROUP BY queries when the ONLY_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 the ONLY_FULL_GROUP_BY SQL mode.
    For example, if name is a nonindexed column, the following query fails with ONLY_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 unique NOT NULL column. This enables MySQL to determine that address is functionally dependent on name; that is, address is uniquely determined by name. (This technique is inapplicable if NULL must be permitted as a valid name value.)

  • Use ANY_VALUE() to refer to address:

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

你可能感兴趣的:(记一次获取会话列表与sql_mode=only_full_group_by错误)