Laravel数据排序问题求助:按创建时间与JobNo组合排序
Laravel 多字段排序实现:按JobNo分组且组内按创建时间升序,组间按组最早创建时间排序
现有数据
| taskid | Createtime | JobNo |
|---|---|---|
| 101337 | 3/7/2024 12:21:21 PM | 23120099AN |
| 101338 | 3/7/2024 12:25:47 PM | 23120099AN |
| 101353 | 3/7/2024 4:58:48 PM | 23110245IR |
| 101363 | 3/7/2024 8:25:57 PM | 23120095AN |
| 101364 | 3/7/2024 8:29:51 PM | 23110245IR |
| 101365 | 3/7/2024 8:30:22 PM | 23110245IR |
| 101369 | 4/7/2024 12:46:25 AM | 23120777AN |
| 101371 | 4/7/2024 12:47:21 AM | 23120777AN |
| 101372 | 4/7/2024 12:47:59 AM | 23120099AN |
| 101373 | 4/7/2024 12:49:06 AM | 23120099AN |
期望排序逻辑
从给出的目标结果来看,实际需求是:
- 相同
JobNo的记录归为一组,组内按Createtime升序排列 - 不同组之间,按该组内最早的Createtime升序排列
实现方案
方法1:Laravel查询构建器(原生SQL子查询)
通过子查询计算每个JobNo的最早创建时间,以此作为组排序依据,再组内按Createtime排序:
$tasks = DB::table('tasks') ->select('*') ->join(DB::raw('(SELECT JobNo, MIN(Createtime) as min_create_time FROM tasks GROUP BY JobNo) as job_groups'), function($join) { $join->on('tasks.JobNo', '=', 'job_groups.JobNo'); }) ->orderBy('job_groups.min_create_time', 'asc') ->orderBy('tasks.Createtime', 'asc') ->get();
方法2:Eloquent模型本地作用域
如果数据对应Task模型,可封装本地作用域复用排序逻辑:
// 在Task模型中添加本地作用域 public function scopeSortByJobAndCreateTime($query) { return $query->select('*') ->join(DB::raw('(SELECT JobNo, MIN(Createtime) as min_create_time FROM tasks GROUP BY JobNo) as job_groups'), function($join) { $join->on('tasks.JobNo', '=', 'job_groups.JobNo'); }) ->orderBy('job_groups.min_create_time', 'asc') ->orderBy('tasks.Createtime', 'asc'); } // 调用方式 $tasks = Task::sortByJobAndCreateTime()->get();
注意事项
- 确保
Createtime字段是数据库datetime/timestamp类型,若为字符串存储,需先转换为时间类型再排序(以MySQL为例):
其他数据库需替换对应时间转换函数。DB::raw('STR_TO_DATE(Createtime, "%m/%d/%Y %h:%i:%s %p") as Createtime')
内容的提问来源于stack exchange,提问作者thomaslam
相关产品推荐
相关产品推荐

