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

Laravel关联查询:如何获取唯一Post记录及全部关联Comments?

解决Laravel DB查询构造器中帖子因关联评论重复的问题

这个问题是因为你使用了内连接(inner join)关联comments表,导致每条评论都会和对应的帖子生成一条独立的记录——帖子有多少条评论,就会重复出现多少次。下面给你两种解决方案,分别适配DB查询构造器和Eloquent模型的场景:

方案一:使用DB查询构造器结合聚合函数

如果你坚持用DB查询构造器,可以通过分组(groupBy)配合数据库的聚合函数,把同一帖子的所有评论整合到一个字段中。以MySQL为例,使用GROUP_CONCAT函数:

DB::table('posts')
    ->join('polls', 'posts.id', '=', 'polls.post_id')
    // 改用leftJoin避免过滤掉没有评论的帖子
    ->leftJoin('comments', 'posts.id', '=', 'comments.post_id')
    ->whereMonth('posts.created_at', '=', date('m', strtotime("01-04-2018")))
    ->select(
        'posts.*',
        'polls.*',
        // 把评论内容拼接成字符串,可根据实际字段调整,比如comments.id、comments.title等
        DB::raw('GROUP_CONCAT(comments.content SEPARATOR "; ") as comments')
    )
    // 注意:需将所有非聚合字段加入groupBy,避免SQL严格模式报错
    ->groupBy('posts.id', 'polls.id')
    ->orderBy('polls.yes', 'desc')
    ->get();

如果你的数据库是PostgreSQL,只需把GROUP_CONCAT替换成STRING_AGG即可:

DB::raw('STRING_AGG(comments.content, "; ") as comments')

方案二:使用Eloquent关联(更推荐)

如果你的项目定义了Eloquent模型,这种方式更符合Laravel的最佳实践,代码可读性和维护性更强。

首先确保你的模型关联关系正确:

// Post模型
class Post extends Model
{
    // 一个帖子对应一个投票(假设关系是一对一)
    public function poll()
    {
        return $this->hasOne(Poll::class);
    }

    // 一个帖子对应多条评论
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

然后通过with()方法预加载关联数据,自动避免重复:

Post::with(['poll', 'comments'])
    ->whereMonth('created_at', '=', date('m', strtotime("01-04-2018")))
    // 关联排序需要指定关联表的字段
    ->orderBy('polls.yes', 'desc')
    ->get();

返回的结果中,每个Post对象会包含poll(单个投票模型)和comments(评论集合)属性,帖子不会重复,所有评论都被整合在对应的属性里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:20:09