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
相关产品推荐
相关产品推荐

