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

Laravel RESTful API去重问题:distinct()为何失效?

问题原因及解决方案

为什么distinct()不生效?

你当前的查询里,select字段包含了contentsname,两条"Java Basic"的记录对应的contentsname分别是"Java Introduction"和"Java Variable",整行数据是完全不同的。distinct()是对整行记录做去重判断,所以会认定这是两条独立记录,自然不会去重。

解决方案

根据你的需求,有几种处理方式:

1. 仅获取课程基础信息(不需要关联内容)

如果不需要返回课程对应的内容,直接查询Course模型即可,无需关联contents表:

$courses = Course::select('id', 'name')->distinct()->get();
return response()->json($courses);

2. 同时返回课程及关联内容(推荐用Eloquent关联)

这是RESTful API返回关联数据的标准方式,既能避免课程重复,又能清晰展示课程与内容的从属关系:

  • 首先在Course模型中定义关联:
// app/Models/Course.php
public function contents()
{
    return $this->hasMany(Content::class);
}
  • 然后查询时通过with()加载关联内容:
$courses = Course::select('id', 'name')
    ->with('contents:id,name,course_id') // 指定要返回的contents字段,避免冗余
    ->get();
return response()->json($courses);

返回的数据结构会变成:

[
    {"id":1,"name":"Java Basic","contents":[{"id":1,"name":"Java Introduction","course_id":1},{"id":2,"name":"Java Variable","course_id":1}]},
    {"id":2,"name":"JDBC","contents":[{"id":3,"name":"Connecting JDBC","course_id":2}]}
]

Flutter端可以遍历每个课程,再嵌套显示对应的内容列表,不会出现课程重复。

3. 用groupBy实现课程去重(仅返回课程信息)

如果坚持用join的方式,可通过groupBy按课程ID和名称分组:

$courses = Course::select('courses.id', 'courses.name')
    ->join('contents', 'contents.course_id', '=', 'courses.id')
    ->groupBy('courses.id', 'courses.name')
    ->get();
return response()->json($courses);

注意:Laravel默认开启严格模式,groupBy必须包含所有select中非聚合的字段(这里就是courses.id和courses.name),否则会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:20:08