首页 > 解决方案 > Laravel 查询获取尚未存在真实数据的日子的虚拟数据

问题描述

我在我的 Laravel 项目中有一个查询,它从我的数据库中返回两个日期之间的数据集合,然后按小时分组(但我可以根据自己的喜好更改),我现在想返回“日期" 对于数据库中存在之前的数据,作为构建日期列表的一种方式,我可以在我的网页中显示这些日期,尽管这些天没有数据,但我的图表看起来还是一致的。

举个例子:

我当前的代码如下(我使用的是 Carbon):

$uptimeData = UptimeChecks::where('user_id', 1)
                        ->where('monitor_id', 1)
                        ->where('checked_at', '>=', '2021-01-01 00:00:00')
                        ->where('checked_at', '<=', '2021-01-30 23:59:59')
                        ->orderBy('checked_at', 'asc')
                        ->select('event', 'checked_at')
                        ->get();

$from = Carbon::now()->subDays(60);
$period = CarbonPeriod::create($from, '2021-01-30 23:59:59');
$dates = $period->toArray();

foreach ($dates as $key => $date) {
  $dates[$key] = Carbon::parse($date)->format('Y-m-d');
}

$uptimeData = collect($uptimeData);
$uptimeData = $uptimeData->merge($dates);

$uptimeDataTimeline = $uptimeData->groupBy(function ($item, $key) {

  if (isset($item->checked_at)) {
    $date = Carbon::parse($item->checked_at);
  } else {
    $date = Carbon::parse($item);
  }

  return $date->format('Y-m-d');
});

即使没有显示“checked_at”列的条目,这是否可以在没有数据的情况下用当天的日期进行欺骗?

更新 03/05 @ 20:30

我更新了我的描述以反映解决此问题的最新尝试,我似乎已经构建了我需要的东西,但是有一些问题:

  1. 在我循环的地方,$dates有没有办法在每个项目中建立一些结构,这样我就不必if/else检查我的所有变量和键?
  2. 出于某种原因,在真实数据之后添加了“假”虚拟日期,例如:1 月 1 日、1 月 2 日、12 月 30 日……我该如何扭转这种情况?

标签: phpsqllaravelquery-builder

解决方案


实现此目的的一种方法是创建所需时间段的日期集合,然后将按日期分组的查询结果合并到其中。

这是一个例子:


$from = '2021-01-01';
$to = '2021-01-31';

$period = CarbonPeriod::create($from, $to);
$dates = collect($period->toArray())->mapWithKeys(function ($date) {
  return [$date->format('Y-m-d') => []];
});

// $dates = ['2021-01-01' => [], '2021-01-02' => [], ...etc]

$uptimeChecks = UptimeChecks::query()
    ->where('user_id', 1)
    ->where('monitor_id', 1)
    ->whereBetween('checked_at', [$from, $to])
    ->orderBy('checked_at', 'asc')
    ->select('event', 'checked_at')
    ->get();

$uptimeDates = $uptimeChecks->groupBy(function ($item, $key) {
  return $item->checked_at->format('Y-m-d');
});

// $uptimeDates = ['2021-01-02' => ['event1', 'event2'], ...etc]

$uptimeData = $dates->merge($uptimeDates);

// $uptimeData = ['2021-01-01' => [], '2021-01-02' => ['event1', 'event2'], ...etc]

这假设您将checked_at字段转换为UptimeChecks模型中的日期。


推荐阅读