一、 MySQL版本
二、 問題描述
1. 問題描述
- 在查詢時使用group by語句,出現錯誤代碼:1055;
- 執行發生錯誤語句:
SELECT
t1.id,
t1.`room_name`,
t2.`room_id`,
t2.`name`
FROM
room t1
LEFT JOIN person t2
ON t1.id = t2.room_id
GROUP BY t1.id
- 結果:
上圖說 select表達式#4-t2.name不是聚合函數列,沒有依賴group by 子句中的列,所以導致報錯
2.ONLY_FULL_GROUP_BY-SQL示例
- 在MySQL5.7之後sql_mode中默認存在ONLY_FULL_GROUP_BY,SQL語句未通過ONLY_FULL_GROUP_BY語義檢查所以報錯。
- ONLY_FULL_GROUP_BY:要求select語句中所查詢出的列必須是在group by中進行聲明,否則就會報錯。
SELECT
COUNT(1)
FROM
room t1
LEFT JOIN person t2 ON t1.id = t2.room_id
GROUP BY
t2.name;
SELECT
*
FROM
room t1
LEFT JOIN person t2 ON t1.id = t2.room_id
GROUP BY
t2.NAME
SELECT
*
FROM
room t1
LEFT JOIN person t2 ON t1.id = t2.room_id
GROUP BY
t1.id,
t2.id
SELECT
t2.NAME
FROM
room t1
LEFT JOIN person t2 ON t1.id = t2.room_id
GROUP BY
t2.NAME
SELECT
t2.name,
t2.room_id
FROM
room t1
LEFT JOIN person t2
ON t1.id = t2.room_id
GROUP BY t2.name
二、解決辦法
1.方法一(臨時)
- 這種方法只能暫時解決1055錯誤,當MySQL服務進行重啓後就會失效,又得重新設置;
- 查詢出所有的sql_mode;
SELECT @@sql_model
- 然後將查詢結果中的ONLY_FULL_GROUP_BY移除後,再重新設置sql_model;
SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
2.方法二(永久)
- 直接通過修改MySQL的my.ini文件,這樣就算MySQL服務重啓後也不會失效;
- 在my.ini文件中添加:
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
三、sql_mode常用值
- ONLY_FULL_GROUP_BY:在SELECT中的列,沒有在GROUP BY中出現,那麼將認爲這個SQL是不合法的,因爲列不在GROUP BY從句中,即只能展示group by的字段,其他均都要報1055的錯;
- STRICT_TRANS_TABLES:在該模式下,如果一個值不能插入到一個事務表中,則中斷當前的操作,對非事務表不做限制;
- NO_AUTO_VALUE_ON_ZERO:影響自增長列的插入。默認設置下,插入0或NULL代表生成下一個自增長值。如果用戶希望插入的值爲0,而該列又是自增長的,那麼這個選項就有用了。
- NO_ZERO_IN_DATE: 在嚴格模式下,不接受月或日部分爲0的日期。如果使用IGNORE選項,我們爲類似的日期插入’0000-00-00’。在非嚴格模式,可以接受該日期,但會生成警告。
- NO_ZERO_DATE:在嚴格模式下,mysql數據庫不允許插入零日期。它實際的行爲受到 strictmode是否開啓的影響2。
- 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後,不能用雙引號來引用字符串,因爲它被解釋爲識別符