Laravel 5.5 GROUP BY不生效,报SQLSTATE[42000] 1055语法错误
咱们先弄明白这个错误的根源:这是MySQL的ONLY_FULL_GROUP_BY严格模式在生效,它有个硬性要求——SELECT子句里所有没有用聚合函数(比如MAX、COUNT)包裹的字段,必须都出现在GROUP BY子句里。
看你写的SQL和Laravel代码,你SELECT了ms_razas.id、ms_razas.nombre、ms_mascotas.id这几个字段,但GROUP BY只指定了ms_mascotas.raza_id,不符合这个规则,所以数据库直接抛出了错误。
给你几个实用的解决思路,你可以根据自己的业务需求选:
思路一:调整GROUP BY,包含所有非聚合字段
如果你的业务需要保留所有SELECT字段的分组逻辑,那就把所有非聚合字段都加到GROUP BY里。对应的Laravel代码修改如下:
$data = Mascota::select("ms_razas.id","ms_razas.nombre","ms_mascotas.raza_id","ms_mascotas.id") ->join("ms_razas", "ms_razas.id", "=", "ms_mascotas.raza_id") ->where("ms_razas.tipo_animal_id", 1) ->groupBy("ms_mascotas.raza_id", "ms_razas.id", "ms_razas.nombre", "ms_mascotas.id") ->get();
不过要注意,这样分组后,如果同一个raza_id下有多条ms_mascotas.id的记录,结果里会保留所有符合条件的行,你得确认这是不是你想要的业务结果。
思路二:用聚合函数处理非分组字段
如果你的业务只需要每个raza_id对应的任意一条宠物记录,那可以用MySQL提供的ANY_VALUE()函数(MySQL 5.7及以上支持),或者用MAX()/MIN()这类聚合函数来包裹不需要分组的字段,告诉数据库忽略该字段的严格分组检查。
比如用ANY_VALUE()的SQL写法:
select ms_razas.id , ms_razas.nombre , ms_mascotas.raza_id , ANY_VALUE(ms_mascotas.id) from ms_mascotas inner join ms_razas on ms_razas.id = ms_mascotas.raza_id where ms_razas.tipo_animal_id = 1 group by ms_mascotas.raza_id
对应的Laravel代码:
use Illuminate\Support\Facades\DB; $data = Mascota::select( "ms_razas.id", "ms_razas.nombre", "ms_mascotas.raza_id", DB::raw("ANY_VALUE(ms_mascotas.id) as mascota_id") ) ->join("ms_razas", "ms_razas.id", "=", "ms_mascotas.raza_id") ->where("ms_razas.tipo_animal_id", 1) ->groupBy("ms_mascotas.raza_id") ->get();
思路三:临时关闭ONLY_FULL_GROUP_BY模式(不推荐)
如果以上两种都不符合你的需求,你可以选择关闭这个严格模式,但我得提醒你,这种做法会降低SQL的规范性,可能导致数据不一致,所以尽量作为最后选项。
你可以在Laravel的config/database.php文件中,找到mysql的配置数组,修改modes项,去掉ONLY_FULL_GROUP_BY:
'mysql' => [ // 其他配置... 'modes' => [ 'STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_DIVISION_BY_ZERO', 'NO_ENGINE_SUBSTITUTION', // 移除ONLY_FULL_GROUP_BY ], ],
内容的提问来源于stack exchange,提问作者Felipe Castillo

