錯誤代碼: 1055
Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ‘xxxx’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
原因
在MySQL5.7.5後,默認開啓了ONLY_FULL_GROUP_BY,所以導致了之前的一些SQL無法正常執行,其實,是我們的SQL不規範造成的,因爲group by 之後,返回的一些數據是不確定的,所以纔會出現這個錯誤。
解決方案
一、禁用ONLY_FULL_GROUP_BY
Linux環境
1.登錄進入MySQL,linux登錄的:mysql -u username -p ,然後輸入密碼,輸入SQL:show variables like ‘%sql_mode’;
2. 編輯my.cnf文件,文件地址一般在:/etc/my.cnf,/etc/mysql/my.cnf,找到sql-mode的位置,去掉ONLY_FULL_GROUP_BY,然後重啓MySQL;有的my.cnf中沒有sql-mode,需要加入:sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,注意要加入到[mysqld]下面,加入到其他地方,重啓後也不生效,具體的如下圖:
3.修改成功後重啓MySQL服務,service mysql restart,重啓好後,再登錄mysql,輸入SQL:show variables like ‘%sql_mode’; 如果沒有ONLY_FULL_GROUP_BY,就說明已經成功了。
Windows下解壓版Mysql
去掉ONLY_FULL_GROUP_BY這個配置,需要更改my.ini配置文件中的配置,如果沒有則自己創建(一般安裝好後按照教程就會創建好這個文件,該配置文件放到mysql安裝目錄根目錄下),配置內容如下:
[mysqld]
#去掉"ONLY_FULL_GROUP_BY"的配置 這個一定寫在[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
#以下兩句具體路徑改爲自己機器上的路徑,分別爲mysql安裝目錄以及mysql存放數據的目錄
basedir=D:\安裝目錄\mysql-5.7.21
datadir=D:\安裝目錄\mysql-5.7.21\data
port=3306
character-set-server=utf8
[client]
port=3306
character-set=utf8
二、 修改SQL,因爲出現這個問題,基本都是因爲這個問題造成的,不確定返回字段可以使用ANY_VALUE(column_name)。
根據mysql文檔,“如果name不是t的主鍵或唯一的NOT NULL列,則此查詢無效。在這種情況下,不可以推斷出功能依賴性併發生錯誤:“
SELECT name, address, MAX(age) FROM t GROUP BY name;
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP
BY clause and contains nonaggregated column 'mydb.t.address' which
is not functionally dependent on columns in GROUP BY clause; this
is incompatible with sql_mode=only_full_group_by
修改ANY_VALUE(‘my_column_name’) my_column_name “在這種情況下,MySQL忽略每個名稱組中的地址值的不確定性並接受查詢。” 使用ANY_VALUE()來引用地址:
修改後語句如下
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
最後附自己修改項目中的一條語句供大家參考
#表結構如下所示
DROP TABLE IF EXISTS `message`;
CREATE TABLE `message` (
`id` INT NOT NULL AUTO_INCREMENT,
`from_id` INT NULL,
`to_id` INT NULL,
`content` TEXT NULL,
`created_date` DATETIME NULL,
`has_read` INT NULL,
`conversation_id` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`),
INDEX `conversation_index` (`conversation_id` ASC),
INDEX `created_date` (`created_date` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
#Mysql5.7.5之前語句
SELECT from_id , to_id, content, has_read, conversation_id, created_date,COUNT(id) FROM (
SELECT id,from_id,to_id,content,created_date,has_read,conversation_id FROM message
WHERE from_id=12 OR to_id=12 ORDER BY created_date DESC)
AS tt GROUP BY conversation_id
ORDER BY created_date
DESC LIMIT 0, 10;
#修改後
SELECT any_value (from_id) , any_value (to_id), any_value (content), any_value (has_read), any_value (conversation_id), any_value(created_date),any_value(COUNT(id)) AS id FROM (
SELECT id,from_id,to_id,content,created_date,has_read,conversation_id FROM message
WHERE from_id=12 OR to_id=12 ORDER BY created_date DESC)
AS tt GROUP BY conversation_id
ORDER BY any_value(created_date)
DESC LIMIT 0, 10;
# 如果是以前的老項目重構,保持列名一致就不需要修改原程序,通過起別名適配 如下所示
SELECT any_value (from_id) AS from_id, any_value (to_id) AS to_id, any_value (content) AS content, any_value (has_read) AS has_read,
any_value (conversation_id) AS conversation_id, any_value(created_date) AS created_date,any_value(COUNT(id)) AS id FROM (
SELECT id,from_id,to_id,content,created_date,has_read,conversation_id FROM message
WHERE from_id=12 OR to_id=12 ORDER BY created_date DESC)
AS tt GROUP BY conversation_id
ORDER BY any_value(created_date)
DESC LIMIT 0, 10;
參考博客:
https://www.cnblogs.com/tygtyg/p/9895481.html
https://www.jianshu.com/p/a430fa1deb85
https://cloud.tencent.com/developer/ask/198993/answer/310023