原文连接:https://blog.csdn.net/hq091117/article/details/79065199mysql
https://blog.csdn.net/allen_tsang/article/details/54892046sql
MySQL 5.7.5后only_full_group_by成为sql_mode的默认选项之一,这可能致使一些sql语句失效。vim
好比下表game:函数
id | group_id | name | score |
---|---|---|---|
1 | A | 小刚 | 20 |
2 | B | 小明 | 19 |
3 | B | 小花 | 17 |
4 | C | 小红 | 18 |
执行sql:
select name, group_id from game group by group_id
(记为sql_make_group)
返回:this
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'game.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
把group by字段group_id
设成primary key 或者 unique NOT NULL。这个方法在实际操做中没什么意义。搜索引擎
使用函数any_value
把报错的字段name
包含起来。如,select any_value(name), group_id from game group by group_id
。spa
在配置文件my.cnf中关闭sql_mode=ONLY_FULL_GROUP_BY.。msqyl的默认配置是sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
。能够把ONLY_FULL_GROUP_BY
去掉,也能够去掉全部选项设置成sql_mode=
,若是你确信其余选项不会形成影响的话。.net
成功的步骤:命令行
命令行打开mysql.cnf,能够用whereis查找rest
sudo vim /etc/mysql/conf.d/mysql.cnf
滚动到文件底部复制并粘贴
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
wq保存并退出
重启MySQL
sudo service mysql restart
执行成功后,返回结果应该是
name | group_id |
---|---|
小刚 | A |
小明 | B |
小红 | C |
对于上述的报错信息,个人理解是select
字段里包含了没有被group by
条件惟一肯定的字段name。
由于执行sql_make_group语句实际上把两行纪录小明
和小花
合并成一行,搜索引擎不知道该返回哪一条,因此认为这样的sql是武断的(arbitrary).
解决办法2和3都是禁止检查返回结果的惟一性。
上述办法能够解决报错的问题,但也说明sql语句自己有逻辑问题。name
字段不该该出如今返回结果,由于它是不肯定的。
考虑这样的需求:按group_id
分组后,找出每组得分最少的人。
执行sql: select any_value(name) as name, group_id, min(score) as score from game group by group_id order by min(score)
返回结果
name | group_id | score |
---|---|---|
小明 | B | 17 |
小红 | C | 18 |
小刚 | A | 20 |
B组的name
是小明
(由于小明
的id更小),而指望结果应该是小花
。
因此单纯使用group by
没法实现这样的需求。可使用临时表的方法:
select id, name,t.group_id, t.score from (select group_id, min(score) as score from game group by group_id order by min(score)) t inner join game on t.group_id=game.group_id and t.score=game.score