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

Laravel按日期分组时如何补全无数据日期(指定数量)

Laravel补全无数据日期分组的实现方法

问题场景

当前使用以下Laravel查询代码:

DowntimeHistoryMonitoring::whereDate('created_at', '<=', now())
    ->get(['id', 'created_at'])
    ->groupBy(function ($item){
       return $item->created_at->format('Y-m-d');
    });   

返回结果仅包含有数据的日期分组:

{
  "2022-11-30": [
    {
      "id": "507a3832-c9d3-4baf-b6a8-ff8100c59897",
      "created_at": "2022-11-30T13:06:42.000000Z"
    },
    {
      "id": "507a3832-c9d3-4baf-b6a8-ff8100c59897",
      "created_at": "2022-11-30T14:06:42.000000Z"
    }
  ],
  "2022-11-29": [
    {
      "id": "507a3832-c9d3-4baf-b6a8-ff8100c59897",
      "created_at": "2022-11-29T13:06:42.000000Z"
    }
  ]
}

需要实现:指定天数(例如5天),补全无对应数据的日期并显示空数组,最终输出如下:

{
  "2022-11-30": [
    {
      "id": "507a3832-c9d3-4baf-b6a8-ff8100c59897",
      "created_at": "2022-11-30T13:06:42.000000Z"
    },
    {
      "id": "507a3832-c9d3-4baf-b6a8-ff8100c59897",
      "created_at": "2022-11-30T14:06:42.000000Z"
    }
  ],
  "2022-11-29": [
    {
      "id": "507a3832-c9d3-4baf-b6a8-ff8100c59897",
      "created_at": "2022-11-29T13:06:42.000000Z"
    }
  ],
  "2022-11-28": [],
  "2022-11-27": [],
  "2022-11-26": []
}

实现步骤

通过生成日期范围集合 + 合并已有数据的方式即可实现,具体代码如下:

1. 生成指定天数的日期范围集合

借助Carbon的CarbonPeriod快速生成连续日期范围,以下示例生成最近5天的日期集合:

use Carbon\CarbonPeriod;

// 生成从4天前到今天的连续日期(共5天)
$datePeriod = CarbonPeriod::create(now()->subDays(4), now());

// 将日期转换为Y-m-d格式的键,值初始化为空数组
$dateRange = collect($datePeriod)->mapWithKeys(function ($date) {
    return [$date->format('Y-m-d') => []];
});

2. 查询并分组已有数据

保留原有查询逻辑,获取已有数据的日期分组结果:

$existingGroups = DowntimeHistoryMonitoring::whereDate('created_at', '<=', now())
    ->get(['id', 'created_at'])
    ->groupBy(function ($item) {
        return $item->created_at->format('Y-m-d');
    });

3. 合并集合补全无数据日期

使用replace方法将已有数据的分组结果覆盖到日期范围集合中,有数据的日期会替换为空数组,无数据的日期保持空数组:

$finalResult = $dateRange->replace($existingGroups);

// 转换为格式化JSON输出
return $finalResult->toJson(JSON_PRETTY_PRINT);

完整代码示例

use Carbon\CarbonPeriod;

public function getDowntimeHistory()
{
    // 1. 生成最近5天的日期范围集合
    $datePeriod = CarbonPeriod::create(now()->subDays(4), now());
    $dateRange = collect($datePeriod)->mapWithKeys(function ($date) {
        return [$date->format('Y-m-d') => []];
    });

    // 2. 查询已有数据并分组
    $existingGroups = DowntimeHistoryMonitoring::whereDate('created_at', '<=', now())
        ->get(['id', 'created_at'])
        ->groupBy(function ($item) {
            return $item->created_at->format('Y-m-d');
        });

    // 3. 合并补全数据
    $finalResult = $dateRange->replace($existingGroups);

    return $finalResult->toJson(JSON_PRETTY_PRINT);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:01:23