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

Laravel数据排序问题求助:按创建时间与JobNo组合排序

Laravel 多字段排序实现:按JobNo分组且组内按创建时间升序,组间按组最早创建时间排序

现有数据

taskidCreatetimeJobNo
1013373/7/2024 12:21:21 PM23120099AN
1013383/7/2024 12:25:47 PM23120099AN
1013533/7/2024 4:58:48 PM23110245IR
1013633/7/2024 8:25:57 PM23120095AN
1013643/7/2024 8:29:51 PM23110245IR
1013653/7/2024 8:30:22 PM23110245IR
1013694/7/2024 12:46:25 AM23120777AN
1013714/7/2024 12:47:21 AM23120777AN
1013724/7/2024 12:47:59 AM23120099AN
1013734/7/2024 12:49:06 AM23120099AN

期望排序逻辑

从给出的目标结果来看,实际需求是:

  1. 相同JobNo的记录归为一组,组内按Createtime升序排列
  2. 不同组之间,按该组内最早的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:34:56