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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:45:21