MySQL異常sql_mode=only_full_group_by 原因:在MySQL 5.7後MySQL預設開啟了SQL_MODE嚴格模式,對數據進行嚴格校驗。會報sql_mode=only_full_group_by錯誤說明寫的SQL語句不嚴謹,對於group by聚合操作,select中的列 ...
MySQL異常sql_mode=only_full_group_by
原因:在MySQL 5.7後MySQL預設開啟了SQL_MODE嚴格模式,對數據進行嚴格校驗。
會報sql_mode=only_full_group_by錯誤說明寫的SQL語句不嚴謹,
對於group by聚合操作,select中的列只能是出現在group by中的列,使用聚合函數除外,如max()、min()等
如以下例子會報錯:
select id, no, uid from user_order group by uid;
改成下麵的SQL則不報錯:
select uid from user_order group by uid;
解決這個問題可以有三個方法:
方法一:
使用 group_concat() 或 any_value()
group_concat():將分到同一組的數據預設用逗號隔開作為返回數據
any_value():將分到同一組的數據里第一條數據的指定列值作為返回數據
修改後語句如下:
select GROUP_CONCAT(id), GROUP_CONCAT(no), uid from user_order group by uid; select any_value(id), any_value(no), uid from user_order group by uid;
方法二:
如果語句太多,變動太大,可以改資料庫配置
首先查看當前sql_mode:
select @@global.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即可:
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
當然,如果想去掉所有限制也是可以的:
SET GLOBAL sql_mode='';
這個方法的好處是不用重啟MySQL生效(需要註意的是在當前會話實例中是不生效的),壞處是重啟後會恢複原樣。
方法三:
永久生效,修改配置文件my.ini
在[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'
保存,重啟後生效。