I have the following subquery:
->whereHas('statuses', function($query){
$query->where('status_id', request('status'));
})->orderBy(...)->paginate();
For simplicity's sake I have hidden the full query. Let's say I have the pivot table user_status
. User has many statuses and a status can also have many users (unusual, I know. Just consider it as an example). So when I query the pivot table user_status
as described above, I get those rows that have the requested status id. But I also want to add the constraint that the row must be the latest one for that particular user (not in entire table). Here is how the user_status table looks like:
+---------+-----------+---------------------+
| user_id | status_id | created_at |
+---------+-----------+---------------------+
| 1 | 1 | 2018-09-03 18:39:14 |
| 1 | 8 | 2018-09-03 18:51:42 |
+---------+-----------+---------------------+
In this scenario, if the requested status
is 1
, I don't want this row to be returned, because status_id
1 is not the latest one for the user_id
1 (see the time difference in create_at
column).
How can I achieve that?
You can achieve that by using another condition with a nested query.
->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();
The nested query will select only latest rows(assuming user_status.id is auto-increment
)
I define a relation in user model as :-
public function latest_statuses() {
return $this->hasMany(Status::class,'user_id','id')->orderBy('created_at','DESC')->take(1);
}
And after that written query as :-
$status = \App\User::with('latest_statuses')->whereHas('latest_statuses', function($query){
return $query->where('status_id', 1);
})->get();
It works for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.