You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel查询报错SQLSTATE[42000]但生成的SQL在phpMyAdmin中可正常运行的问题咨询

解决Laravel GROUP BY 1055错误(SQL执行正常但Laravel报错)

这个问题的核心矛盾,是MySQL的ONLY_FULL_GROUP_BY SQL模式在Laravel和phpMyAdmin的执行环境中配置不一致导致的:

为什么会出现这种差异?

Laravel默认在数据库配置中开启了严格模式(包含ONLY_FULL_GROUP_BY规则),而你的phpMyAdmin连接的MySQL实例大概率没有开启这个模式:

  • 当ONLY_FULL_GROUP_BY开启时,MySQL会强制要求:SELECT语句中所有未被聚合函数处理的列,必须出现在GROUP BY子句中,否则直接抛出1055错误;
  • 当这个模式关闭时,MySQL会自动忽略这个限制,返回分组内该列的任意值,这就是你在phpMyAdmin里执行SQL能正常出结果的原因。

三种可行的解决方法

方法1:调整Laravel的数据库严格模式(最简单快捷)

打开项目根目录下的config/database.php,找到MySQL的配置块,通过修改strict参数或自定义modes来移除ONLY_FULL_GROUP_BY:

方案A:完全关闭严格模式(不推荐,会丢失其他严格校验能力)

'mysql' => [
    // ...其他配置项
    'strict' => false,
],

方案B:保留其他严格模式,仅移除ONLY_FULL_GROUP_BY(推荐)

'mysql' => [
    // ...其他配置项
    'strict' => true,
    'modes' => [
        'STRICT_TRANS_TABLES',
        'NO_ZERO_IN_DATE',
        'NO_ZERO_DATE',
        'ERROR_FOR_DIVISION_BY_ZERO',
        'NO_ENGINE_SUBSTITUTION',
    ],
],

修改完成后,记得清除配置缓存:php artisan config:clear

方法2:修改查询语句,符合ONLY_FULL_GROUP_BY规则

把SELECT中所有未被聚合的列,全部添加到GROUP BY子句中。因为你用了makineler.*,所以需要把makineler表的所有字段、u.user_name、o.oyun_adi都加入分组:

$MakinelerQuery = Makineler::leftjoin('users as u','u.id','makineler.yetkilisi')
    ->leftjoin('oyunlar as o','o.id','makineler.oyun_id')
    ->leftjoin('sifre_hareket as sh','sh.makine_id','makineler.id'); 

$MakinelerQuery = $MakinelerQuery->select('makineler.*','u.user_name','o.oyun_adi'); 
$MakinelerQuery = $MakinelerQuery->selectRaw('max(sh.sifre_tarihi) as maxSifreTarihi'); 
// 将所有非聚合列加入GROUP BY
$MakinelerQuery = $MakinelerQuery->groupBy(
    'makineler.id',
    'makineler.makine_adi',
    'makineler.yetkilisi',
    'makineler.oyun_id',
    // ...补充makineler表的其他字段
    'u.user_name',
    'o.oyun_adi'
); 

$fetchMakineler = $MakinelerQuery->get();

注意:如果makineler表字段较多,这种方法会比较繁琐,适合字段少的场景。

方法3:用ANY_VALUE()函数包裹非聚合列(适合需要保留严格模式的场景)

MySQL提供了ANY_VALUE()函数,用来明确告诉数据库:可以返回分组内该列的任意值,以此绕过ONLY_FULL_GROUP_BY的校验:

use Illuminate\Support\Facades\DB;

$MakinelerQuery = Makineler::leftjoin('users as u','u.id','makineler.yetkilisi')
    ->leftjoin('oyunlar as o','o.id','makineler.oyun_id')
    ->leftjoin('sifre_hareket as sh','sh.makine_id','makineler.id'); 

// 用ANY_VALUE()处理非聚合列
$MakinelerQuery = $MakinelerQuery->select(
    DB::raw('makineler.*'),
    DB::raw('ANY_VALUE(u.user_name) as user_name'),
    DB::raw('ANY_VALUE(o.oyun_adi) as oyun_adi')
); 
$MakinelerQuery = $MakinelerQuery->selectRaw('max(sh.sifre_tarihi) as maxSifreTarihi'); 
$MakinelerQuery = $MakinelerQuery->groupBy('makineler.id'); 

$fetchMakineler = $MakinelerQuery->get();

总结

  • 追求效率选方法1,想遵循严格SQL标准选方法2或3;
  • 你可以在Laravel代码里执行DB::select('SELECT @@sql_mode;'),再在phpMyAdmin里执行同样语句,对比结果就能直观看到两边的模式差异。

内容的提问来源于stack exchange,提问作者poison pawn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:57:32