原文連接: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