我有两张一对多的桌子。我的任务很简单,我需要从关系表中每个父项的最后一个应用条件。
第一个表是状态:
| 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)"
但有了它,我也会得到搭档1,即使他的最后地位是5,但在历史上,他有地位1。
我创建了sql查询来获得这个结果,但我认为要完成这样一个简单的任务,这是相当复杂的。而且我认为一定有一些简单的拉拉夫尔方法:
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
我的目标是只得到搭档2,因为只有他有最后的状态1。