Laravel根据pivot中间表状态查询玩家可用模块的DB查询问题
问题排查与修复方案
原查询问题原因
- 存在语法笔误:
where('module_player.player_id, '=', 1)中字段名多带了一个逗号,会导致字段识别错误 - 玩家ID条件位置错误:将
player_id判断写在全局where中,会直接过滤掉所有没有关联中间表记录的模块(你需要的未开始模块会被全部排除) - 状态判断逻辑不全:
where('module_player.status', '!=', 2)对未关联模块的null状态判断不生效,也会过滤未开始模块 - 冗余关联:不需要关联players表,已有玩家ID即可完成查询
正确实现代码
$playerId = 1; $modules = \DB::table('modules') ->leftJoin('module_player', function ($join) use ($playerId) { // 左连接时就限定对应玩家的关联记录,未关联的模块会保留null值 $join->on('modules.id', '=', 'module_player.module_id') ->where('module_player.player_id', '=', $playerId); }) ->where(function ($query) { // 匹配两类有效模块:未开始/已开始未完成 $query->whereNull('module_player.module_id') ->orWhere('module_player.status', '=', 1); }) ->select('modules.id', 'modules.name', 'modules.image', 'modules.mandatory') ->paginate(10);
逻辑验证
对应你提供的测试数据,该查询返回结果为:
- 模块1:存在关联记录且status=1,符合条件
- 模块3:无对应关联记录,符合条件
完全匹配需求。
内容的提问来源于stack exchange,提问作者Miguel Heredia
相关产品推荐
相关产品推荐

