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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:32:39