Laravel Eloquent如何查询同时包含所有指定关联标签的Post记录
问题原因
你原来的写法中,whereIn('tag_id', [1,4]) 是对单条关联的tag记录做判断,只要有任意一条关联记录满足条件就会被筛选出来,所以得到的是包含tag1或tag4的帖子,不符合同时包含两个标签的需求。
实现方案
方案1:多次调用whereHas(最直观,适合标签数量少的场景)
对每个需要同时满足的标签,单独加一层whereHas校验,代码如下:
// 要查询同时拥有tag_id=1和tag_id=4的帖子 $posts = Post::whereHas('tags', function($q) { $q->where('tag_id', 1); })->whereHas('tags', function($q) { $q->where('tag_id', 4); })->get();
如果要查询的标签ID是动态数组,可以循环追加:
$tagIds = [1,4]; $posts = Post::query(); foreach ($tagIds as $tagId) { $posts->whereHas('tags', function($q) use ($tagId) { $q->where('tag_id', $tagId); }); } $posts = $posts->get();
方案2:分组统计匹配的标签数量(适合标签数量多的场景,性能更优)
通过whereIn筛选出所有符合的关联标签,再分组统计每个帖子匹配到的标签数量,等于标签总数的就是同时满足所有标签的帖子:
$tagIds = [1,4]; $posts = Post::whereHas('tags', function($q) use ($tagIds) { $q->whereIn('tag_id', $tagIds); }, '=', count($tagIds))->get();
注意:如果你的
post_tags中间表存在同一个帖子和同一个标签多次关联的重复数据,需要在闭包里加distinct避免统计错误:$q->whereIn('tag_id', $tagIds)->distinct();
内容的提问来源于stack exchange,提问作者Hadi Sharghi
相关产品推荐
相关产品推荐

