今天sql一對多關聯查詢發現一個錯誤,提示說查詢的字段不在group by的子句中,因為sql_mode是only_full_group_by。
報錯信息:
#1055 - Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'xt_sc.t_comment.content' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
執行的sql語句
SELECT n.id, n.title, n.qq, u.username, c.content, c.create_time FROM `t_need` AS `n` LEFT JOIN `t_users` `u` ON `n`.`user_id`=`u`.`id` INNER JOIN ( SELECT max(id) as id,n_id,content,create_time FROM `t_comment` GROUP BY `n_id` ) AS `c` ON `n`.`id`=`c`.`n_id` WHERE `n`.`status` = 2 AND `n`.`form` = 1 GROUP BY `n`.`id` ORDER BY `stick` DESC,`n`.`update_time` DESC LIMIT 0,30
問題出現的原因:
MySQL 5.7.5及以上功能依賴檢測功能。如果啟用了ONLY_FULL_GROUP_BY SQL模式(默認情況下),MySQL將拒絕選擇列表,HAVING條件或ORDER BY列表的查詢引用在GROUP BY子句中既未命名的非集合列,也不在功能上依賴於它們。(5.7.5之前,MySQL沒有檢測到功能依賴關系,默認情況下不啟用ONLY_FULL_GROUP_BY。有關5.7.5之前的行為的說明,請參見“MySQL 5.6參考手冊”。)
查看mysql本地的sql_mode命令:
select @@sql_mode; show variables like 'sql_mode';
輸出sql_mode的值:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZER
_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
確實第一個是only_full_group_by,這個模式說明對於GROUP BY聚合操作,如果在SELECT中的列,沒有在GROUP BY中出現,那么將認為這個SQL是不合法的,因為列不在GROUP BY從句中。就是說不允許select的列沒有出現在group by的子句中。
在5.7.5以上,sql的默認模式配置是ONLY_FULL_GROUP_BY。
解決辦法1:
簡單粗暴的解決方法是刪除ONLY_FULL_GROUP_BY,不推薦
在數據庫控制台輸入命令:SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
然后再執行查詢語句,可以正常查詢出結果
解決辦法2:
優化sql語句
SELECT n.id, n.title, n.qq, u.username, c.content, c.create_time FROM `t_need` AS `n` LEFT JOIN `t_users` `u` ON `n`.`user_id`=`u`.`id` INNER JOIN ( SELECT a.id,a.n_id,a.content,a.create_time FROM `t_comment` AS `a` LEFT JOIN( SELECT max(id) as id,n_id FROM `t_comment` GROUP BY `n_id` ) AS `b` ON `b`.`n_id`=`a`.`n_id` WHERE `a`.`id` = `b`.`id` ) AS `c` ON `n`.`id` = `c`.`n_id` WHERE `n`.`status` = 2 AND `n`.`form` = 1 GROUP BY `n`.`id` ORDER BY `stick` DESC,`n`.`update_time` DESC LIMIT 0,30
執行以上查詢語句,可以正常查詢出結果。
done!