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

如何通过Eloquent/查询构造器获取最后状态为working的工单

解决Laravel Eloquent获取最后状态为"working"的工单问题

嘿,我明白你遇到的问题了——last()方法在这里没法像你想的那样工作,因为它是Eloquent集合的方法,只能在已经把数据从数据库拉出来之后用,没法在数据库查询阶段帮你筛选出每个工单的最后一条状态记录。

要实现你要的效果(只保留那些最新状态是"working"的工单),我们需要先找到每个工单对应的最新状态记录,再从中筛选状态为"working"的。下面给你几种可行的方案:

方案1:用子查询关联筛选(推荐,Eloquent风格)

假设你的Status表有created_at字段用来判断状态的先后顺序(或者用自增的id字段也可以),我们可以先写一个子查询获取每个工单的最新状态记录,再关联筛选:

$tickets = Ticket::whereHas('status_table', function ($query) {
    // 子查询:获取当前工单的最新状态记录ID
    $latestStatus = Status::select('id')
        ->whereColumn('ticket_id', 'tickets.id')
        ->orderBy('created_at', 'desc') // 按时间倒序,取最新的
        ->limit(1);

    $query->whereIn('id', $latestStatus)
          ->where('status_column', 'working');
})->get();

方案2:先分组获取最新状态ID,再筛选

这种方式先拿到所有工单的最新状态ID集合,再用这个集合去筛选:

// 第一步:分组获取每个工单的最新状态ID(用MAX(id)或者按created_at排序取最新都可以)
$latestStatusIds = Status::selectRaw('MAX(id) as id, ticket_id')
    ->groupBy('ticket_id')
    ->pluck('id');

// 第二步:筛选出最新状态是working的工单
$tickets = Ticket::whereHas('status_table', function ($query) use ($latestStatusIds) {
    $query->whereIn('id', $latestStatusIds)
          ->where('status_column', 'working');
})->get();

方案3:用查询构造器的JOIN写法

如果你更习惯原生查询风格,也可以用JOIN子查询的方式:

$tickets = Ticket::join(
    // 子查询:按工单分组,取每个工单的最新状态
    DB::raw('(SELECT ticket_id, status_column FROM statuses ORDER BY ticket_id, created_at DESC) AS latest_status'),
    function ($join) {
        $join->on('tickets.id', '=', 'latest_status.ticket_id');
    }
)
->where('latest_status.status_column', 'working')
->groupBy('tickets.id') // 避免重复(可选,取决于你的数据结构)
->select('tickets.*')
->get();

为什么你的原代码无效?

再解释下你原来的代码问题:$query->last()是试图在查询构造器上调用集合方法,这根本行不通——查询构造器是用来构建SQL语句的,而last()是在数据已经被取出成为Collection之后才会生效的方法,所以数据库根本不会理解这个指令。

用上面的方案测试你的示例数据:

  • 工单1的最新状态是created,会被排除
  • 工单2的最新状态是working,会被保留
  • 工单3的最新状态是finished,会被排除
    最终结果正好是你要的工单ID#2。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:33:37