如果行是最新的,则是雄辩的子查询

问题描述 投票:2回答:2

我有以下子查询:

->whereHas('statuses', function($query){
           $query->where('status_id', request('status'));
})->orderBy(...)->paginate();

为简单起见,我隐藏了完整的查询。假设我有数据透视表user_status。用户有很多状态,状态也可以有很多用户(不寻常,我知道。只是将其视为一个例子)。因此,当我如上所述查询数据透视表user_status时,我得到那些具有请求状态ID的行。但我还想添加约束,该行必须是该特定用户的最新行(而不是整个表)。以下是user_status表的外观:

+---------+-----------+---------------------+
| user_id | status_id | created_at          |
+---------+-----------+---------------------+
|       1 |         1 | 2018-09-03 18:39:14 |
|       1 |         8 | 2018-09-03 18:51:42 |
+---------+-----------+---------------------+

在这种情况下,如果请求的status1,我不希望返回此行,因为status_id 1不是user_id 1的最新行(请参阅create_at列中的时间差)。

我怎样才能做到这一点?

php laravel eloquent
2个回答
0
投票

您可以通过使用嵌套查询的另一个条件来实现这一点。

->whereHas('statuses', function($query){
       $query->where('status_id', request('status'))
             ->whereIn('user_status.id', function($query) {
                $query->selectRaw('MAX(id)')
                      ->from('user_status')
                      ->groupBy('user_id');
             });
})->orderBy(...)->paginate();

嵌套查询将仅选择最新行(假设user_status.id为auto-increment


0
投票

我在用户模型中定义了一个关系: -

public function latest_statuses() {
        return $this->hasMany(Status::class,'user_id','id')->orderBy('created_at','DESC')->take(1);
}

之后的书面查询如下: -

$status = \App\User::with('latest_statuses')->whereHas('latest_statuses', function($query){
           return $query->where('status_id', 1);
        })->get();

这个对我有用。

© www.soinside.com 2019 - 2024. All rights reserved.