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

Laravel如何获取最后状态为Closed的应用列表(排除非终态)

最后状态为Closed的应用列表

用户提供的数据表结构

表1:applications

id(pk)name
1naveed

表2:statuses

id(pk)statusapplication_id(fk)
1pending1
2submitted1
3closed1
4observation1

需求说明

获取最后一条状态为Closed的应用列表,仅将最后状态是Closed的应用加入列表,注意:不能将只要有过Closed状态的应用加入列表。

错误实现代码

错误代码1

$applicationsWithClosedStatus = Application::whereHas('statuses', function ($query) {
    $query->where('status', 'closed');
})->get();

问题:只要应用历史中有过Closed状态就会被筛选,不满足“最后状态为Closed”的要求。

错误代码2

public function status() {
    return $this->hasOne(Status::class)->latest();
}

$applicationsWithLastClosedStatus = Application::whereHas('status', function ($query) {
    $query->where('status', 'closed');
})->get();

问题:hasOne+latest()定义的关联,在whereHas查询时,Laravel会检查是否存在符合条件的状态记录,而非强制匹配最新的那条,可能导致历史有Closed状态的应用被错误筛选。

正确的Laravel实现方式

方法一:子查询关联(兼容所有Laravel版本)

通过子查询先获取每个应用的最新状态ID,再关联状态表筛选出最新状态为Closed的应用:

$latestStatuses = Status::select('application_id', \DB::raw('MAX(id) as latest_status_id'))
    ->groupBy('application_id');

$applications = Application::joinSub($latestStatuses, 'latest_statuses', function ($join) {
    $join->on('applications.id', '=', 'latest_statuses.application_id');
})
->join('statuses', 'statuses.id', '=', 'latest_statuses.latest_status_id')
->where('statuses.status', 'closed')
->select('applications.*')
->get();

方法二:whereExists子查询

直接通过whereExists判断应用的最新状态是否为Closed:

$applications = Application::whereExists(function ($query) {
    $query->select(\DB::raw(1))
        ->from('statuses as latest_status')
        ->whereColumn('latest_status.application_id', 'applications.id')
        ->where('latest_status.status', 'closed')
        ->whereNotExists(function ($subQuery) {
            $subQuery->select(\DB::raw(1))
                ->from('statuses as newer_status')
                ->whereColumn('newer_status.application_id', 'latest_status.application_id')
                ->where('newer_status.id', '>', 'latest_status.id');
        });
})->get();

方法三:Eloquent关联(Laravel 8.42+)

在Application模型中定义专门的最新状态关联:

public function latestStatus()
{
    return $this->hasOne(Status::class)->latestOfMany();
}

然后使用whereHas查询:

$applications = Application::whereHas('latestStatus', function ($query) {
    $query->where('status', 'closed');
})->get();

latestOfMany()是Laravel官方为获取关联最新记录提供的方法,相比latest()更可靠,能确保whereHas匹配的是应用的最后一条状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:26:07