1. 程式人生 > 其它 >MySql報錯only_full_group_by的解決辦法

MySql報錯only_full_group_by的解決辦法

前段時間我在一個新環境裡部署程式時遇到MySql報錯only_full_group_by,之前已經遇到過一次同樣的問題,當時沒有總結經驗,導致這次解決時耗費了不少時間,這裡把本次的處理過程進行記錄總結,同時分享給大家

MySql資料庫報錯如下,從字面意思理解是select後面查詢的欄位沒有出現在group by中

[42000][1055] Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'levi.emp.ename' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

MySql在低版本(5.7.x以下)中允許select後面的非聚合列不出現在group by中。以下sql在低版本中是可以執行的,但是在5.7及以上版本會報錯

-- 注意ename沒有出現在group by中

select ename, job, sum(sal) from emp group by job;

MySql從5.7版本開始預設開啟only_full_group_by規則,規則核心原則如下,沒有遵循原則的sql會被認為是不合法的sql

  1. order by後面的列必須是在select後面存在的

  2. select、having或order by後面存在的非聚合列必須全部在group by中存問題解決

可以通過三種方式解決報錯問題

第一種,修改sql使其遵守only_full_group_by規則

第二種,將MySql的版本降到5.7以下

第三種,關閉only_full_group_by規則

第一種方式適用於sql比較少的情況,如果程式中有大量的sql沒有遵循only_full_group_by規則,這種方式修改起來會很浪費時間

第二種方式不建議使用,高版本很明顯的一個好處是安全性高,如果降低版本會有一定的風險。

第三種方式比較推薦,不過要重啟資料庫,步驟如下

  1. 檢視是否開啟了only_full_group_by規則校驗,在資料庫中執行如下sql
*SELECT @@GLOBAL.sql_mode;*

*SELECT @@SESSION.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*
  1. 關閉only_full_group_by的規則校驗,關閉規則校驗需要執行如下sql。以下兩個sql單引號中的內容是第一步查詢的結果去掉“,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 @@SESSION.sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

3.上面是改變全域性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';