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

Laravel中按玩家去重获取Top Ticket的Eloquent实现咨询

Laravel Eloquent 实现玩家唯一的Top工单查询

方法一:用窗口函数实现(推荐,逻辑清晰)

直接在Eloquent里封装MySQL的ROW_NUMBER()窗口函数,和你原生查询的逻辑一致:

$topTickets = Ticket::select('tickets.*')
    ->selectSub(function ($query) {
        $query->selectRaw('ROW_NUMBER() OVER (PARTITION BY player_id ORDER BY score DESC, id ASC) as row_num')
            ->from('tickets');
    }, 'row_num')
    ->where('row_num', 1)
    ->orderBy('score', 'DESC')
    ->orderBy('id', 'ASC')
    ->get();
  • PARTITION BY player_id:把工单按玩家分组,每个玩家的工单单独处理
  • ORDER BY score DESC, id ASC:组内先按得分从高到低排,得分相同就选ID更小的
  • 最后只保留每组的第一条(row_num=1),再对结果整体按得分、ID排序

方法二:子查询筛选最优工单

如果不想用窗口函数,也可以通过子查询锁定每个玩家的目标工单ID:

$topTickets = Ticket::whereIn('id', function ($query) {
    $query->selectRaw('MIN(id)')
        ->from('tickets')
        ->groupBy('player_id')
        ->havingRaw('score = (SELECT MAX(score) FROM tickets t2 WHERE t2.player_id = tickets.player_id)');
})
->orderBy('score', 'DESC')
->orderBy('id', 'ASC')
->get();
  • 子查询按玩家分组,先找到每个玩家的最高得分,再取该得分下ID最小的工单
  • 主查询通过ID筛选出这些工单,再做整体排序

为什么DISTINCT没用?

distinct是对查询结果的所有字段做去重,没法实现“按玩家分组后保留特定规则记录”的逻辑,所以满足不了你的需求。

内容的提问来源于stack exchange,提问作者Nikola Vi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:12:39