Laravel get latest record for each group(Laravel 获取每个组的最新记录)
问题描述
我正在尝试将一些原始 SQL 迁移到模型上的 Eloquent(或查询生成器)范围.我的零件历史记录表如下所示:
I am trying to migrate some Raw SQL to an Eloquent (or Query Builder) scope on my model. My Parts history table looks like this:
+----+---------+--------+------------+
| id | part_id | status | created_at |
+----+---------+--------+------------+
| 1 | 1 | 1 | ... |
| 2 | 1 | 2 | ... |
| 3 | 2 | 1 | ... |
| 4 | 1 | 2 | ... |
| 5 | 2 | 2 | ... |
| 6 | 1 | 3 | ... |
请注意,同一个 part_id 可以有多个状态相同的条目.
Notice the same part_id can have multiple entries where the status is the same.
目前我使用以下选择最新状态:
At the moment I use the following to select the latest status:
$part = Part::leftjoin( DB::raw("
(SELECT t1.part_id, ph.status, t1.part_status_at
FROM (
SELECT part_id, max(created_at) part_status_at
FROM part_histories
GROUP BY part_id) t1
JOIN part_histories ph ON ph.part_id = t1.part_id AND t1.part_status_at = ph.created_at) as t2
)", 't2.part_id', '=', 'parts.id')->where( ... )
我正在尝试在零件模型上制作一个范围,到目前为止我有这个:
I am trying to make a scope on the parts model out of this, so far I have this:
public function scopeWithLatestStatus($query)
{
return $query->join(DB::raw('part_histories ph'), function ($join) {
$join->on('ph.part_id', '=', 't1.id')->on('t1.part_status_at', '=', 'ph.created_at');
})
->from(DB::raw('(select part_id as id, max(created_at) part_status_at from part_histories GROUP BY part_id) t1'))
->select('t1.id', 'ph.part_status', 't1.part_status_at');
}
这是其中的一部分(但仍然使用一些原始 SQL),我就是想不通其余的
which is part way there (but still using some raw SQL), I just can't figure out the rest
推荐答案
您可以将查询重写为左连接以获得相同的结果
You could rewrite your query as left join to get the same results
select a.*
from part_histories a
left join part_histories b on a.part_id = b.part_id
and a.created_at < b.created_at
where b.part_id is null
我猜你可以在你的范围内轻松转换上面的查询,比如
and I guess you can transform easily above query in your scope something like
public function scopeWithLatestStatus($query)
{
return $query->leftJoin('part_histories as b', function ($join) {
$join->on('a.part_id', '=', 'b.part_id')
->where('a.created_at', '<', 'b.created_at');
})
->whereNull('b.part_id')
->from('part_histories as a')
->select('a.*');
}
Laravel Eloquent 选择具有最大值的所有行created_at
Laravel - 获取最后一个条目每种 UID 类型
Laravel Eloquent 按最近记录分组
使用上述查询作为 has
关系进行编辑,要获取每个部分的最新历史记录,您可以定义一个 hasOne
关系,如
Edit using above query as has
relation,To get the latest history for each part you can define a hasOne
relation like
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateSupportFacadesDB;
class Part extends Model
{
public function latest_history()
{
return $this->hasOne(AppModelsPartHistory::class, 'part_id')
->leftJoin('part_histories as p1', function ($join) {
$join->on('part_histories.part_id', '=', 'p1.part_id')
->whereRaw(DB::raw('part_histories.created_at < p1.created_at'));
})->whereNull('p1.part_id')
->select('part_histories.*');
}
}
然后要加载具有最新历史记录的零件,您可以将上面定义的映射加载为
And then to load parts with their latest history you could eager load above defined mapping as
$parts = Part::with('latest_history')->get();
您将拥有一份零件清单以及最新的历史记录
You will have a list of parts along with latest history as
Array
(
[0] => Array
(
[id] => 1
[title] => P1
[latest_history] => Array
(
[id] => 6
[created_at] => 2018-06-16 08:25:10
[status] => 1
[part_id] => 1
)
)
....
)
这篇关于Laravel 获取每个组的最新记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Laravel 获取每个组的最新记录
基础教程推荐
- 在 CakePHP 2.0 中使用 Html Helper 时未定义的变量 2021-01-01
- 使用 PDO 转义列名 2021-01-01
- 如何在 Symfony 和 Doctrine 中实现多对多和一对多? 2022-01-01
- 找不到类“AppHttpControllersDB",我也无法使用新模型 2022-01-01
- Doctrine 2 - 在多对多关系中记录更改 2022-01-01
- 如何在 XAMPP 上启用 mysqli? 2021-01-01
- 在 yii2 中迁移时出现异常“找不到驱动程序" 2022-01-01
- HTTP 与 FTP 上传 2021-01-01
- phpmyadmin 错误“#1062 - 密钥 1 的重复条目‘1’" 2022-01-01
- PHP 守护进程/worker 环境 2022-01-01