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

Laravel Eloquent多表关联分组查询问题求助

Laravel Eloquent 关联多表并按分类分组实现方案

我来帮你搞定这个Eloquent关联分组的需求~先从模型关联定义开始,再给你两种实用的查询方案:

第一步:定义模型关联

首先得确保两个模型的关联关系配置正确,这样Eloquent才能顺畅关联数据表:

Check 模型(对应 tbl_checks)

class Check extends Model
{
    protected $table = 'tbl_checks';

    // 一个检查记录属于一个人员
    public function person()
    {
        return $this->belongsTo(Person::class, 'person_id', 'id');
    }
}

Person 模型(对应 tbl_persons)

class Person extends Model
{
    protected $table = 'tbl_persons';

    // 一个人员可以有多个检查记录
    public function checks()
    {
        return $this->hasMany(Check::class, 'person_id', 'id');
    }
}

第二步:实现分组查询

根据你的需求,我提供两种常用实现方式,你可以按需选择:

方式一:Eloquent集合分组(更贴合Laravel风格)

如果核心需求是获取所有关联检查记录的人员,并按category分组,这种方式不用写原生JOIN,直接利用模型关联和集合方法就能搞定:

// 过滤出有检查记录的人员,预加载关联的检查数据,最后按分类分组
$groupedPersons = Person::has('checks')
    ->with('checks') // 预加载避免N+1查询问题
    ->get()
    ->groupBy('category');

返回的$groupedPersons是一个集合,键是分类名称,值是对应分类下的Person模型集合(每个模型都包含关联的检查记录)。

方式二:数据库层面分组(适合需要聚合统计的场景)

如果需要在数据库层面直接完成分组+统计(比如统计每个分类的检查记录数),可以用JOIN配合GROUP BY:

use Illuminate\Support\Facades\DB;

$groupedStats = Check::with('person')
    ->join('tbl_persons', 'tbl_checks.person_id', '=', 'tbl_persons.id')
    ->groupBy('tbl_persons.category')
    // 可选:添加聚合统计字段
    ->select(
        'tbl_persons.category',
        DB::raw('COUNT(tbl_checks.id) as total_checks'), // 该分类下的检查记录总数
        DB::raw('COUNT(DISTINCT tbl_persons.id) as total_people') // 该分类下的人员总数
    )
    ->get();

这种方式直接在数据库完成分组统计,返回结果包含分类名称和对应的统计数据。

小提醒

  • 如果MySQL开启了ONLY_FULL_GROUP_BY模式(默认开启),数据库层面的GROUP BY需要确保SELECT的字段要么在GROUP BY中,要么是聚合函数,否则会报错。
  • 优先推荐方式一的集合分组,代码可读性更高,更符合Eloquent的ORM设计思路。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:29:49