Laravel中按p_id分组后取每组trust排序的前两条数据
解决Laravel中按分组取指定排序前N条数据的问题
首先看你的需求和期望结果,核心是按p_id分组,每个p_id下再按trust值分组,每个trust组内按time升序排序后取前2条数据,同时最终结果按p_id升序、trust降序排列。
要实现这个需求,Laravel的查询构造器可以结合SQL窗口函数来完成,这是处理分组内排序取数的最优方案,具体代码如下:
$result = DB::table('a16s') ->select('id', 'p_id', 'u_id', 'trust', 'time') // 用窗口函数给每个p_id+trust分组内的条目按time升序编号 ->selectRaw('ROW_NUMBER() OVER (PARTITION BY p_id, trust ORDER BY time ASC) as rn') // 筛选每个分组内的前2条 ->having('rn', '<=', 2) // 按需求整理最终排序 ->orderBy('p_id') ->orderByDesc('trust') ->orderBy('rn') ->get();
代码解释:
- 窗口函数
ROW_NUMBER():PARTITION BY p_id, trust表示把数据按p_id和trust组合成小分组,ORDER BY time ASC指定每个小分组内的排序规则(和你的期望结果匹配),rn就是每个小分组内的条目序号。 - 筛选前2条:通过
having('rn', '<=', 2)保留每个小分组内的前2条数据。 - 最终排序:按
p_id升序、trust降序、分组内序号rn升序排列,完全贴合你给出的期望结果格式。
如果后续需要调整分组内的排序规则(比如改成time降序),只需要修改窗口函数里的ORDER BY time ASC为ORDER BY time DESC即可。
内容的提问来源于stack exchange,提问作者robspin
相关产品推荐
相关产品推荐

