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

如何在Laravel中使用Query Builder实现包含WHERE NOT IN子查询的功能

实现方案

我们可以直接用Laravel Query Builder的子查询、UNION、原生表达式组合实现完全等价的逻辑,比手写SQL更易维护,还自带参数绑定防注入。

前置说明:假设你要查询的用户ID为$userId(示例中原SQL是1,可根据业务动态传入),使用前需要先导入DB门面:use Illuminate\Support\Facades\DB;

完整实现代码

// 构造排除的任务ID子查询(三个表的UNION)
$excludedTaskIds = DB::table('skipped_user_tasks')
    ->where('user_id', $userId)
    ->select('task_id')
    ->union(DB::table('shown_user_tasks')->where('user_id', $userId)->select('task_id'))
    ->union(DB::table('current_user_tasks')->where('user_id', $userId)->select('task_id'));

// 主查询
$tasks = DB::table('tasks')
    ->distinct()
    ->select([
        'tasks.id',
        'tasks.category_id',
        // 用EXISTS实现completed字段判断,比原写法查询效率更高,逻辑完全等价
        DB::raw('CASE WHEN EXISTS (SELECT 1 FROM completed_user_tasks WHERE user_id = ? AND task_id = tasks.id) THEN true ELSE false END AS completed', [$userId])
    ])
    ->whereNotIn('tasks.id', $excludedTaskIds)
    ->get();

补充说明

  • 上述代码逻辑和你提供的原生SQL完全一致,返回的结果结构也完全相同
  • 如果你的项目用Eloquent模型操作tasks表,只需要把主查询的DB::table('tasks')替换为Task::query()即可,其余部分无需修改

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:39:04