You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent按价格分组筛选每组最新created_at数据问题

Laravel中按价格连续区间分组取每组最新记录的解决方案

你的核心需求不是全局按price分组取最新,而是要捕捉连续相同price的批次分组——当价格从1010切换到1007再切回1010时,这两个1010属于不同的价格阶段,各自阶段的最后一条记录都需要保留。之前的方法失效,是因为它们都做了全局price去重,自然会丢失id=2的条目。

以下是两种可行的解决方案:

方法一:数据库层面用窗口函数(推荐,适用于MySQL 8.0+)

利用LAG()窗口函数识别价格变化节点,为连续相同price的记录分配分组ID,再取每组的最后一条:

$alerts = DB::table(function ($query) {
    $query->selectRaw('*, 
        SUM(CASE WHEN price != LAG(price, 1, -1) OVER (ORDER BY created_at) THEN 1 ELSE 0 END) OVER (ORDER BY created_at) AS group_id')
        ->from('alerts_logs');
}, 'with_groups')
->selectRaw('MAX(id) as id, price, MAX(created_at) as created_at')
->groupBy('group_id', 'price')
->orderBy('created_at')
->get();

逻辑说明:

  1. LAG(price, 1, -1)获取当前记录的上一条price,默认值设为-1确保第一条记录触发分组
  2. 当当前price与上一条不同时,SUM()累加生成新的group_id,连续相同price的记录会被分到同一组
  3. 最后按group_id分组,取每组的最大created_at(对应最新记录)

方法二:Collection层面遍历处理(兼容旧版本数据库)

如果数据库不支持窗口函数,可通过遍历Collection实现连续价格分组:

$alerts = AlertsLog::orderBy('created_at')->get();
$uniqueAlerts = collect();
$currentPrice = null;
$currentGroup = collect();

foreach ($alerts as $alert) {
    if ($alert->price !== $currentPrice) {
        // 切换价格时,把上一组的最后一条加入结果
        if (!$currentGroup->isEmpty()) {
            $uniqueAlerts->push($currentGroup->sortByDesc('created_at')->first());
        }
        $currentPrice = $alert->price;
        $currentGroup = collect();
    }
    $currentGroup->push($alert);
}

// 加入最后一组的最新记录
if (!$currentGroup->isEmpty()) {
    $uniqueAlerts->push($currentGroup->sortByDesc('created_at')->first());
}

// 重置索引
$uniqueAlerts = $uniqueAlerts->values();

逻辑说明:

  1. 先按created_at正序排序,保证遍历顺序是时间先后
  2. 遍历过程中把连续相同price的记录归为一组,切换价格时保存上一组的最新记录
  3. 最后处理剩余的最后一组

为什么之前的方法失效?

  • groupBy子查询方式:全局按price分组,只会取每个price的最大id(对应全局最新的记录),因此1010的最大id是5,自然丢失id=2
  • Collection::unique('price'):按price全局去重,由于你先按created_at倒序,每个price只会保留第一条出现的最新记录(1010保留id=5),同样丢失id=2

内容的提问来源于stack exchange,提问作者Yashgupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 02:10:26