mysql5.7以后group by 報錯 sql_mode=only_full_group_by的解決方法


一、發現問題

1、查詢語句

SELECT * from class group by class_name;

 

2、報錯結果

..... this is incompatible with sql_mode=only_full_group_by;

 

 

二、原因

mysql 5.6 版本后。默認啟用了ONLY_FULL_GROUP_BY。

ONLY_FULL_GROUP_BY是MySQL提供的一個sql_mode,通過這個sql_mode來提供SQL語句GROUP BY合法性的檢查。

http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_only_full_group_by

this is incompatible with sql_mode=only_full_group_by這句話提示了這違背了mysql的規則,only fully group by,也就是說在執行的時候先分組,根據查詢的字段(select的字段)在分組的內容中取出,所以查詢的字段全部都應該在group by分組條件內;一種情況例外,查詢字段中如果含有聚合函數的字段不用包含在group by中,就像我上面的count(id)。

后來發現Order by排序條件的字段也必須要在group by內,排序的字段也是從分組的字段中取出。 不明白的可以去看一下。

 

 

三、解決方案

1、修改 sql-mode

修改文件 vim /etc/my.cnf.d/mysql-server.cnf

添加語句 sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

注意還是那個面那個  sql-mode ,  不是  sql_mode

注:網上很多說法是修改文件  vim /etc/my.cnf ,但是我這個不是,原因我也不知道,我是 yum 安裝的 mysql

 

 

 

 

 

 

2、重啟 mysqld

3、查詢 sql_mode

 

 

 

4、使用 group by 驗證

 

 

 

 

四、sql_mode

1、mysql5.0以后的三種模式

1)ANSI模式

寬松模式,更改語法和行為,使其更符合標准SQL。對插入數據進行校驗,如果不符合定義類型或長度,對數據類型調整或截斷保存,報warning警告。對於本文開頭中提到的錯誤,可以先把sql_mode設置為ANSI模式,這樣便可以插入數據,而對於除數為0的結果的字段值,數據庫將會用NULL值代替。

2)TRADITIONAL模式

嚴格模式,當向mysql數據庫插入數據時,進行數據的嚴格校驗,保證錯誤數據不能插入,報error錯誤,而不僅僅是警告。用於事物時,會進行事物的回滾。 注釋:一旦發現錯誤立即放棄INSERT/UPDATE。如果你使用非事務存儲引擎,這種方式不是你想要的,因為出現錯誤前進行的數據更改不會“滾動”,結果是更新“只進行了一部分”。

3)STRICT_TRANS_TABLES模式

嚴格模式,進行數據的嚴格校驗,錯誤數據不能插入,報error錯誤。如果不能將給定的值插入到事務表中,則放棄該語句。對於非事務表,如果值出現在單行語句或多行語句的第1行,則放棄該語句。

 

2、模式關鍵字

1)ONLY_FULL_GROUP_BY

對於GROUP BY聚合操作,如果在SELECT中的列、HAVING或者ORDER BY子句的列,沒有在GROUP BY中出現,那么這個SQL是不合法的。

 

2)NO_AUTO_VALUE_ON_ZERO

該值影響自增長列的插入。默認設置下,插入0或NULL代表生成下一個自增長值。如果用戶希望插入的值為0,該列又是自增長的,那么這個選項就有用了。

 

3)STRICT_TRANS_TABLES

在該模式下,如果一個值不能插入到一個事物表中,則中斷當前的操作,對非事物表不做限制

 

4)NO_ZERO_IN_DATE

在嚴格模式,不接受月或日部分為0的日期。如果使用IGNORE選項,我們為類似的日期插入'0000-00-00'。在非嚴格模式,可以接受該日期,但會生成警告。

 

5)NO_ZERO_DATE

在嚴格模式,不要將 '0000-00-00'做為合法日期。你仍然可以用IGNORE選項插入零日期。在非嚴格模式,可以接受該日期,但會生成警告。

 

6)ERROR_FOR_DIVISION_BY_ZERO

在INSERT或UPDATE過程中,如果數據被零除,則產生錯誤而非警告。如 果未給出該模式,那么數據被零除時MySQL返回NULL

 

7)NO_AUTO_CREATE_USER

禁止GRANT創建密碼為空的用戶

 

8)NO_ENGINE_SUBSTITUTION

如果需要的存儲引擎被禁用或未編譯,那么拋出錯誤。不設置此值時,用默認的存儲引擎替代,並拋出一個異常

 

9)PIPES_AS_CONCAT

將"||"視為字符串的連接操作符而非或運算符,這和Oracle數據庫是一樣的,也和字符串的拼接函數Concat相類似

 

10)ANSI_QUOTES

啟用ANSI_QUOTES后,不能用雙引號來引用字符串,因為它被解釋為識別符

 

 

3、sql_mode 設置

1)各種級別的 sql_mode

 

2)修改sql_mode

global級別:set global sql_mode='...';  (這里是修改的字段,所以 sql_mode , 不同於配置文件 的 sql-mode )

session級別:set session sql_mode=''...;  (這里是修改的字段,所以 sql_mode , 不同於配置文件 的 sql-mode )

修改配置文件級別的就在上面的解決方案里面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM