Laravel多关联查询:获取单部系列剧的唯一播出频道
解决Serie关联频道去重的问题
我明白你的困扰——现在的写法会把同一个频道重复输出,因为一部剧的多个剧集可能都关联了同一个频道。这里有两种靠谱的解决方式,你可以根据自己的场景选择:
方法一:在模型层直接定义关联(推荐,更高效)
既然我们要从Serie直接拿到对应的不重复频道,不如在Serie模型里新增一个关联方法,让数据库层面就帮我们完成去重,避免冗余数据传输:
// Serie模型 public function channels() { return Channel::whereHas('episodes', function ($query) { // 关联到该Serie下的所有剧集 $query->whereHas('season', fn($q) => $q->where('serie_id', $this->id)); })->distinct(); }
或者用更贴合Eloquent风格的关联链式调用:
public function channels() { return $this->belongsToMany(Channel::class, 'episodes', 'serie_id', 'id') ->join('programmation', 'episodes.id', '=', 'programmation.episode_id') ->select('channels.*') ->distinct(); }
然后在控制器里预加载这个关联(避免N+1查询问题):
$serie = Serie::with('channels')->find($yourSerieId);
最后在Blade视图里直接遍历即可,完全不会有重复:
@foreach($serie->channels as $chaine) {{ $chaine->name }} @endforeach
方法二:在视图层通过集合处理(快速实现,适合小数据量)
如果不想改动模型,也可以利用Laravel集合的方法在视图里去重。首先确保控制器预加载了所有关联:
$serie = Serie::with('episodes.chaines')->find($yourSerieId);
然后在Blade里先把所有频道收集起来,再去重:
@php // 先把所有剧集的频道平铺成一个集合,再按id去重 $uniqueChannels = $serie->episodes->flatMap(fn($episode) => $episode->chaines)->unique('id'); @endphp @foreach($uniqueChannels as $chaine) {{ $chaine->name }} @endforeach
小提示
- 用
distinct()或者unique('id')的时候,要确保Channel模型的主键是id,如果你的主键字段不一样,记得改成对应的字段名。 - 优先选方法一,因为数据库层面的去重比在PHP里处理集合性能更好,尤其是数据量大的时候。
内容的提问来源于stack exchange,提问作者Charlotte
相关产品推荐
相关产品推荐

