Laravel 5.6中如何统计玩家的获胜游戏数量?
解决Laravel中统计玩家获胜游戏数的问题
嗨,我来帮你搞定这个统计需求~ 你已经用withCount('games')拿到了每位玩家的总游戏数,要统计获胜数其实只需要在这个基础上稍作调整,利用Eloquent的withCount支持闭包过滤的特性就能实现,下面给你几种可行的方案:
方案一:直接在withCount中添加过滤条件
这是最简洁的方式,直接在withCount里给games关联加一个别名,同时通过闭包筛选出该玩家作为winner的游戏:
use Illuminate\Support\Facades\DB; // 在PlayersController的index方法中 $players = Player::withCount([ 'games', // 保留原有的总游戏数统计 'games as won_games_count' => function ($query) { // 筛选出games表中winner等于当前玩家id的记录 $query->where('games.winner', '=', DB::raw('players.id')); } ])->get();
这样查询后,每个Player实例就会多出两个属性:
games_count:玩家参与的总游戏数won_games_count:玩家获胜的游戏数
这里用DB::raw('players.id')是为了让SQL能正确关联到players表的id字段,避免Laravel把它解析成字符串常量。
方案二:定义专门的获胜游戏关联
如果你希望代码更清晰,可以在Player模型中定义一个专门的关联来表示玩家获胜的游戏,然后再用withCount统计:
首先在Player模型里添加关联:
public function wonGames() { return $this->belongsToMany(Game::class) ->where('games.winner', '=', DB::raw('players.id')); }
然后在控制器中调用:
$players = Player::withCount(['games', 'wonGames'])->get();
此时每个玩家实例的won_games_count属性就是获胜游戏数,和方案一效果一致,只是把过滤逻辑封装到了模型关联里,更符合MVC的代码组织方式。
方案三:使用原生SQL Join(适合复杂统计场景)
如果后续有更复杂的统计需求,也可以用原生的Join和聚合函数来实现:
$players = Player::select('players.*', DB::raw('COUNT(DISTINCT game_player.game_id) as games_count'), DB::raw('COUNT(DISTINCT CASE WHEN games.winner = players.id THEN games.id END) as won_games_count') ) ->leftJoin('game_player', 'players.id', '=', 'game_player.player_id') ->leftJoin('games', 'game_player.game_id', '=', 'games.id') ->groupBy('players.id') ->get();
这种方式更灵活,但代码相对冗长,适合需要同时统计多个复杂指标的场景。
注意事项
- 确保
games表的winner字段存储的是玩家的id,且字段类型和players.id一致(比如都是integer) - 如果你的关联表有额外字段,记得在关联定义中正确设置,但这里不影响统计逻辑
内容的提问来源于stack exchange,提问作者Gilko
相关产品推荐
相关产品推荐

