【问题标题】:Laravel - DB Query items based on pivot table statusLaravel - 基于数据透视表状态的数据库查询项目
【发布时间】:2021-11-27 07:59:44
【问题描述】:

我的应用中有一个玩家可以完成的模块列表,当他们完成时,他们必须停止出现在“可用模块”列表中。我有表格“玩家”、“模块”和“模块播放器”来保存关系。

所以,对于“可用模块”列表,我只想显示尚未启动的模块(也就是 module_player 表上没有记录)或已经启动但尚未完成的模块(也就是 module_player 表中的状态 1) .

假设我有:

球员表

id name
1 Player_1
2 Player_2

模块表

id name
1 Module_1
2 Module_2
3 Module_3

module_player 表

module_id player_id status
1 1 1
2 1 2

“可用列表”应仅返回模块 1(已启动但未完成)和模块 3(未启动)。

问题是我只在“可用列表”中获取模块 1,这是我的查询显然有问题:

        $modules = \DB::table('modules')
            ->join('module_player', 'modules.id', '=', 'module_player.module_id', 'left')
            ->join('players', 'module_player.player_id', '=', 'players.id', 'left')
            ->where('module_player.status', '!=', 2)
            ->where('module_player.player_id, '=', 1)
            ->select('modules.id', 'modules.name', 'modules.image', 'modules.mandatory')->paginate(10);

谢谢

【问题讨论】:

  • 你为什么不使用关系?
  • hmm 因为我不仅想获取与播放器有关系的模块,还想获取还没有关系的模块,并分页
  • 所以你想要 module_player 中状态为 1 且此表中不存在的模块。像 1 和 3?
  • 是的,这正是我需要的

标签: php mysql laravel eloquent left-join


【解决方案1】:

当你使用时

`where('module_player.player_id, '=', 1)`

您将仅获得 player_id 为 1 的记录,因此请尝试使用 whereNotIn 进行以下查询

$modules = \DB::table('modules')
                ->join('module_player', 'modules.id', '=', 'module_player.module_id', 'left')
                ->join('players', 'module_player.player_id', '=', 'players.id', 'left')
                ->whereNotIn('modules.id', function($query){
                     $query->select('module_id')
                     ->from('module_player')
                     ->where('status', 2);
                })
                ->select('modules.id', 'modules.name', 'modules.image', 'modules.mandatory')->paginate(10);

如果您想为任何特定用户使用它,您可以在use() 中传递 player_id

->whereNotIn('modules.id', function($query) use($player_id){
                         $query->select('module_id')
                         ->from('module_player')
                         ->from('player_id', $player_id)
                         ->where('status', 2);
                    })

【讨论】:

  • 谢谢,第一个有效。希望稍微解释一下为什么,因为我认为无论哪个用户登录,结果都是一样的(这就是我使用您删除的行的原因)。但是我尝试使用两个不同的用户启动/完成不同的模块,结果还可以。我在查询中看不到它怎么知道,例如,如果我没有在任何地方使用登录的 player_id,玩家 1 的模块 1 已完成,模块 2 已启动,玩家 2 的模块 1 已启动,没有别的。谢谢!
【解决方案2】:

删除 ->where('module_player.player_id, '=', 1) 行,因为它会返回 player_id 为 1 的记录。然后尝试下面的查询

$modules = \DB::table('modules')
            ->join('module_player', 'modules.id', '=', 'module_player.module_id', 'left')
            ->join('players', 'module_player.player_id', '=', 'players.id', 'left')
            ->where('module_player.status', '!=', 2)
            ->select('modules.id', 'modules.name', 'modules.image', 'modules.mandatory')->paginate(10);

【讨论】:

    猜你喜欢
    • 2016-12-12
    • 2018-11-11
    • 2015-06-24
    • 1970-01-01
    • 2016-06-30
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多