我在使用 Eloquent 根据 Laravel 中的最大日期进行分组和选择行时遇到问题。我有一个名为 AlertsLog 的表,其中包含 id、price 和created_at 列。目标是按价格对行进行分组,并为每个组选择具有最新created_at 的条目。我尝试了多种方法,包括 groupBy、max 和子查询,但我仍然缺少一些预期的结果。
这是我的 sql 虚拟数据的样子
[
{"id": 1, "price": 1010, "created_at": "2023-11-09 01:22 PM"},
{"id": 2, "price": 1010, "created_at": "2023-11-09 01:35 PM"},//the price
{"id": 3, "price": 1007, "created_at": "2023-11-09 01:40 PM"},//the price has changed
{"id": 4, "price": 1007, "created_at": "2023-11-09 01:45 PM"},
{"id": 5, "price": 1010, "created_at": "2023-11-09 01:50 PM"},//the price has changed
{"id": 6, "price": 1015, "created_at": "2023-11-09 01:55 PM"},//the price has changed
{"id": 7, "price": 1015, "created_at": "2023-11-09 02:00 PM"} //the latest price
]
我想展示的是
[
{"id":2,"price":1010,"created_at":"2023-11-09 01:35 PM"},
{"id":4,"price":1007,"created_at":"2023-11-09 01:45 PM"},
{"id":5,"price":1010,"created_at":"2023-11-09 01:50 PM"},
{"id":7,"price":1015,"created_at":"2023-11-09 02:00 PM"}
]
到目前为止我使用 group by 尝试过的:
$uniqueAlerts = DB::table('alerts_logs')
->whereIn('id', function ($query) {
$query->select(DB::raw('MAX(id)'))
->from('alerts_logs')
->groupBy('price');
})
->orderBy('created_at', 'desc')
->get();
使用独特:
$alerts = AlertsLog::orderBy('created_at', 'desc')->get();
return $uniqueAlerts = $alerts->unique('price')->sort(function ($a, $b) {
return $b->created_at <=> $a->created_at;
})->values()->toArray();
甚至使用循环,但它们都产生相同的结果,包括 ids 4,5,7 但缺少 2 ,
谢谢!
我找到了一种使用自连接的解决方案,但结果返回1,2,5,6 ...
查看我的解决方案,也许可以改进它:
AlertsLog::from('AlertsLog as a')
->leftJoin('AlertsLog as b', function ($join) {
$join->on('a.id', '=', DB::raw('(b.id + 1)'));
})
->whereColumn('a.price', '!=', 'b.price')
//->orWhereNull('b.id')
->select('a.*')
->orderBy('a.id')
->get();
mysql 查询是:
select `a`.*
from `AlertsLog` as `a`
left join `AlertsLog` as `b` on `a`.`id` = (b.id + 1)
where `a`.`price` != `b`.`price`
order by `a`.`id` asc