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

