我有以下子查询:
->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 |
+---------+-----------+---------------------+
在这种情况下,如果请求的status
是1
,我不希望返回此行,因为status_id
1不是user_id
1的最新行(请参阅create_at
列中的时间差)。
我怎样才能做到这一点?
您可以通过使用嵌套查询的另一个条件来实现这一点。
->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
)
我在用户模型中定义了一个关系: -
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();
这个对我有用。