一、出錯原因
最近因為開發數據庫與部署數據庫版本不同,帶來了幾個問題,其中only_full_group_by問題是之前沒有遇到的。
具體報錯如下
1 [Err] 1055 - Expression #1 of ORDER BY clause is not
in GROUP BY clause and contains nonaggregated column 'information_schema.PROFILING.SEQ'
which is not functionally dependent on columns in GROUP BY clause;
this is incompatible with sql_mode=only_full_group_by
可以看出是因為sql_mode中設置了only_full_group_by模式引起的,
sql_mode的作用是什么呢?
模式定義mysql會支持哪些sql語法。以及應執行哪種數據驗證檢查。最終達到的目標:適應在不同環境中適應mysql,因為可
以根據各自的程序設置不同的操作模式。
在only_full_group_by這種模式下,使用group by語句進行查詢時,所要查詢的語句必須依賴於group by子句中所列出的列,也就是group by要以查詢的字段
作為分組依據,這里是要查詢的所有字段。
另外常用的sql_mode有:
ONLY_FULL_GROUP_BY: 對於GROUP BY聚合操作,如果在SELECT中的列,沒有在GROUP BY中出現,那么這個SQL是不合法的,因為列不在GROUP BY從句中 NO_AUTO_VALUE_ON_ZERO: 該值影響自增長列的插入。默認設置下,插入0或NULL代表生成下一個自增長值。如果用戶 希望插入的值為0,而該列又是自增長的,那么這個選項就有用了。 STRICT_TRANS_TABLES: 在該模式下,如果一個值不能插入到一個事務表中,則中斷當前的操作,對非事務表不做限制 NO_ZERO_IN_DATE: 在嚴格模式下,不允許日期和月份為零 NO_ZERO_DATE: 設置該值,mysql數據庫不允許插入零日期,插入零日期會拋出錯誤而不是警告。 ERROR_FOR_DIVISION_BY_ZERO: 在INSERT或UPDATE過程中,如果數據被零除,則產生錯誤而非警告。如 果未給出該模式,那么數據被零除時MySQL返回NULL NO_AUTO_CREATE_USER: 禁止GRANT創建密碼為空的用戶 NO_ENGINE_SUBSTITUTION: 如果需要的存儲引擎被禁用或未編譯,那么拋出錯誤。不設置此值時,用默認的存儲引擎替代,並拋出一個異常 PIPES_AS_CONCAT: 將”||”視為字符串的連接操作符而非或運算符,這和Oracle數據庫是一樣的,也和字符串的拼接函數Concat相類似 ANSI_QUOTES: 啟用ANSI_QUOTES后,不能用雙引號來引用字符串,因為它被解釋為識別符
我們可以使用
select @@global.sql_mode; //全局配置
查詢
也可以通過
select @@sql_mode;//已存在數據庫配置
查詢
二、解決方法
1.使用any_value()函數,這個函數對不需要group by的字段有效,等同於關閉only_full_group_by,但是這樣難免會遺漏某個字段,所以不推薦使用。
2.暫時性關閉(可以通過select @@sql_mode查出sql_mode以后去掉ONLY_FULL_GROUP_BY后復制過來):
set sql_mode=' ' //改變已經存在的數據庫sql_mode
set @@global.sql_mode=' ' //改變全局配置sql_mode
以上配置在重啟服務以后失效
3.更改配置文件(推薦使用)
linux系統更改/etc/my.cnf文件,使用vi命令打開,如果有sql_mode=...的注釋就把注釋打開,如果沒有就加上sql_mode=...(可以通過select @@sql_mode查出sql_mode以后去掉ONLY_FULL_GROUP_BY后復制過來)
windows下配置文件是安裝目錄下的my.ini文件,其余同上