Laravel如何获取分类ID不存在于分类表中的帖子数据
解决方法:获取关联分类已删除的帖子
嘿,这个问题我之前踩过坑!你用!=做连接的方式之所以会返回重复数据,是因为每条帖子都会和分类表里所有不匹配的分类记录做一次关联——比如你分类表有4条有效数据(ID1、2、6、7),那那条category_id=4的帖子就会和这4条分类各匹配一次,自然就输出了4条重复的帖子。
下面给你几种靠谱的实现方式,按常用程度排序:
1. 左连接(Left Join)+ 空值筛选(最直观)
左连接会保留posts表的所有数据,对于没有对应分类的帖子,categories表的关联字段会是null,我们只需要筛选这些记录即可:
$cpost = DB::table('posts') ->leftJoin('categories', 'posts.category_id', '=', 'categories.id') ->whereNull('categories.id') ->select('posts.*') // 只取帖子表的字段,避免冗余 ->paginate(5);
这个方法逻辑清晰,性能也不错,是处理这类“关联记录不存在”场景的首选。
2. WhereNotIn + 子查询
先查询所有有效的分类ID,再筛选帖子的category_id不在这个集合里的记录:
$cpost = DB::table('posts') ->whereNotIn('category_id', function($query) { // 子查询获取所有存在的分类ID $query->select('id')->from('categories'); }) ->select('posts.*') ->paginate(5);
这种方式适合需要明确排除特定ID集合的场景,同时也会包含category_id为null的帖子(如果你的业务允许这种情况的话)。
3. WhereNotExists 反向查询
通过whereNotExists检查每条帖子是否不存在对应的分类记录:
$cpost = DB::table('posts') ->whereNotExists(function($query) { $query->select(DB::raw(1)) ->from('categories') ->whereRaw('categories.id = posts.category_id'); }) ->select('posts.*') ->paginate(5);
这个查询的语义非常直接:“找出所有在分类表中没有对应ID的帖子”,性能和左连接相当,具体取决于你的数据库优化器。
为什么你之前的查询会重复?
你用的join默认是内连接(Inner Join),加上!=条件后,数据库会把每条帖子和分类表里所有不匹配的分类记录进行关联。比如分类表有4条数据,那一条无对应分类的帖子就会生成4条关联结果,最终返回4条重复的帖子数据——这显然不是你想要的。
内容的提问来源于stack exchange,提问作者Anonymous shooter
相关产品推荐
相关产品推荐

