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

