У меня есть две таблицы с отношением один ко многим.Моя задача довольно проста, мне нужно для каждого родительского последнего элемента из таблицы отношений, где применяется условие.
Первая таблица - это статус:
| id | partner_id | status | created_at |
|----|------------|--------|---------------------|
| 1 | 1 | 1 | 2018-01-01 00:00:00 |
| 2 | 1 | 5 | 2018-02-01 00:00:00 |
| 3 | 2 | 1 | 2018-01-01 00:00:00 |
Отношение
public function partner()
{
return $this->belongsTo(Partner::class, 'partner_id');
}
Второе - партнеры:
| id | name |
|----|-----------|
| 1 | partner_1 |
| 2 | partner_2 |
Отношение:
public function status()
{
return $this->hasMany(Status::class, 'partner_id')->orderBy('id', 'desc');
}
Допустим, я хочу получить всех партнеров, где их последний статус равен 1. Я попробовал это:
Partner::with('status')
->whereHas('status', function ($query) use ($status) {
$query->where('status', $status);
})
->get();
Результат таков:
"select * from `partners` where exists (select * from `status` where `partners`.`id` = `status`.`partner_id` and `status` = 1)"
Но ся также получу partner_1, даже если его последний статус равен 5, но в истории он имел статус 1.
Я создал SQL-запрос, чтобы получить это, но я думаю, что сделать такую простую задачу довольно сложно.И также я думаю, что должен быть какой-то простой подход Laravel:
select p.id, ps.status, ps.newest_status
from partners as p
INNER JOIN (SELECT a.created_at AS newest_status, a.partner_id, a.status
FROM status as a
INNER JOIN (
SELECT max(created_at) as newest_status, partner_id
FROM status
GROUP BY partner_id
) as b ON a.partner_id = b.partner_id AND a.created_at = b.newest_status
) ps ON p.id = ps.partner_id and ps.status = 1
GROUP BY p.id
Моя цель - получить только partner_2, потому что только он имеет последний статус 1.