如何用Laravel Query Builder查询同时修完两门课程的用户
解决Laravel中筛选同时修完多门课程的用户问题
你遇到的问题确实是whereIn的逻辑问题——它是OR的关联,只要用户修了列表里的任意一门课就会被选中,所以Jane只修了course-1也被包含进来了。下面给你两种对应需求的Laravel写法,一种和你给出的原生SQL完全对应,另一种是更灵活的分组统计方案:
方法一:对应原生SQL的多表关联写法
这种写法直接复刻你提供的原生SQL逻辑,通过两次关联courses表并分别指定课程条件:
User::join('courses as c1', 'c1.user_id', '=', 'users.id') ->join('courses as c2', 'c2.user_id', '=', 'users.id') ->where('c1.name', 'course-1') ->where('c2.name', 'course-2') ->select('users.*') // 只选择用户表的字段,避免重复的courses字段 ->distinct() // 确保不会返回重复的用户记录 ->get();
这里给courses表取了两个别名c1和c2,分别关联同一个用户ID,然后分别过滤出修了course-1和course-2的记录,最终就能得到同时修完两门课的用户。
方法二:分组统计法(更灵活)
如果之后需要筛选修完3门、4门课程的用户,这种方法会更易于扩展,不需要多次关联表:
User::join('courses', 'courses.user_id', '=', 'users.id') ->whereIn('courses.name', ['course-1', 'course-2']) ->groupBy('users.id') ->havingRaw('COUNT(DISTINCT courses.name) = 2') // 统计用户修的不同课程数量等于2 ->select('users.*') ->get();
逻辑是:先筛选出修了目标课程列表中任意一门的用户,然后按用户ID分组,只保留那些修过的不同课程数量刚好等于目标课程数的用户。这样就能确保用户同时修完了所有指定课程。
这两种方法都能正确返回只有John的结果,你可以根据自己的需求选择合适的写法~
内容的提问来源于stack exchange,提问作者vaja sinauridze
相关产品推荐
相关产品推荐

