今天在測試環境遇到一個問題,本地測試是沒有問題,在測試環境sql報錯了: nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'dt.vDateTime' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by;
剛開始覺得很奇怪,本地測試的時候沒有問題,為什么在測試環境就sql報錯了,后來想到leader說過的sql嚴格模式。百度了一下報錯信息,在這里紀錄一下。
ONLY_FULL_GROUP_BY是MySQL提供的一個sql_mode,通過這個sql_mode來提供SQL語句GROUP BY合法性的檢查,在MySQL的sql_mode沒有ONLY_FULL_GROUP_BY語義時。一條select語句,MySQL允許target list中輸出的表達式是除聚集函數或group by column以外的表達式。ONLY_FULL_GROUP_BY的語義就是確定select target list中的所有列的值都是明確語義,簡單的說來,在ONLY_FULL_GROUP_BY模式下,target list中的值要么是來自於聚集函數的結果,要么是來自於group by list中的表達式的值
mysql> select id+1 as a from tt group by a order by id+1; +------+ | a | +------+ | 2 | | 3 | +------+ 2 rows in set (0.00 sec)
mysql允許target list中對於非聚集函數的alias column被group by、having condition以及order by語句引用(version 5.7中允許having condition引用alias column,version 5.6不支持having condition引用alias column),從上面兩條語句可以看出,group by和order by中引用了alias column。
我的sql報錯是因為我的order by並沒有出現在group by list中,而且也不是聚合修飾的;
select a1 from table group by a1 order by a2
紀錄一下網上找到的一些解決方案:
1.命令行輸入:
set @@GLOBAL.sql_mode='';
set sql_mode ='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!
這樣只是session級別的,在mysql重啟后,還是會有ONLY_FULL_GROUP_BY;
2.改my.ini 配置(如果你們mysql 沒有這個文件,就把my-default.ini 改成my.ini,我這個版本就是沒有my.ini配置問題)
在 [mysqld]和[mysql]下添加
SET sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE