PHP升级后Yii网站遇MySQL 1055错误的解决咨询
问题解答
1. 修改my.cnf是否可行?为何无效?
修改配置文件关闭ONLY_FULL_GROUP_BY是可行的,但你修改后无效大概率是以下原因:
- 配置文件路径错误:Ubuntu 22.04搭配MySQL 8.0时,实际生效的主配置文件是
/etc/mysql/mysql.conf.d/mysqld.cnf,而非/etc/mysql/my.cnf(后者通常只是作为配置入口,不直接存放核心参数)。 - 配置项位置错误:必须将
sql_mode配置放在[mysqld]区块内才会生效,否则MySQL不会读取该参数。正确的配置内容应为:[mysqld] sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" - 未确认配置是否生效:重启MySQL后,需登录MySQL执行
SELECT @@sql_mode;,检查返回结果中是否已移除ONLY_FULL_GROUP_BY。如果仍存在,可能是会话级或数据库级的sql_mode覆盖了全局配置。 - 重启方式不正确:需确保执行的是
sudo systemctl restart mysql命令重启MySQL服务,而非其他无关服务;部分场景下可能需要重启PHP-FPM才能让应用读取新的数据库配置。
2. 如何正确修改findAllDevicesByUser方法以符合SQL语法?
要解决1055错误,核心是让SELECT列表中的非聚合列全部出现在GROUP BY子句中,或者用聚合函数包裹不需要分组的列。以下是针对Yii框架的具体修改方案:
方案一:将所有非聚合列加入GROUP BY
假设原方法的查询代码类似:
public static function findAllDevicesByUser($userId) { $criteria = new CDbCriteria; $criteria->select = 'device_id, device_name, device_type, COUNT(*) as bind_count'; $criteria->condition = 'user_id = :userId'; $criteria->params = [':userId' => $userId]; $criteria->group = 'device_id'; // 仅分组了device_id,导致错误 return self::model()->findAll($criteria); }
修改后:
public static function findAllDevicesByUser($userId) { $criteria = new CDbCriteria; $criteria->select = 'device_id, device_name, device_type, COUNT(*) as bind_count'; $criteria->condition = 'user_id = :userId'; $criteria->params = [':userId' => $userId]; $criteria->group = 'device_id, device_name, device_type'; // 加入所有非聚合列 return self::model()->findAll($criteria); }
方案二:用聚合函数包裹非分组列
如果某些列(如device_name)在同一device_id下是唯一的,可以用MAX()或MIN()等聚合函数包裹,避免加入GROUP BY:
public static function findAllDevicesByUser($userId) { $criteria = new CDbCriteria; $criteria->select = 'device_id, MAX(device_name) as device_name, MAX(device_type) as device_type, COUNT(*) as bind_count'; $criteria->condition = 'user_id = :userId'; $criteria->params = [':userId' => $userId]; $criteria->group = 'device_id'; // 仅保留需要分组的列 return self::model()->findAll($criteria); }
注意事项
- 修改代码后需清除Yii的缓存(可通过删除
protected/runtime目录下的缓存文件实现),同时重启PHP-FPM确保代码生效; - 若使用原生SQL而非CDbCriteria,需遵循同样的规则:
SELECT中的非聚合列必须全部出现在GROUP BY中,或用聚合函数处理。
内容的提问来源于stack exchange,提问作者coderookie
相关产品推荐
相关产品推荐

