简体   繁体   English

Laravel 查询获取尚未存在真实数据的天的虚拟数据

[英]Laravel query get dummy data for days where no real data exists yet

I've got a query in my Laravel project that returns a collection of data from my database between two dates, it's then grouped by the hour (but I can change this to my liking), I'd now like to return the "dates" for data before they existed in the database as a way of building up a list of dates that I can display in my web page, eve though there will be no data for these days, my chart would look consistent.我在我的 Laravel 项目中有一个查询,它从我的数据库中返回两个日期之间的数据集合,然后按小时分组(但我可以根据自己的喜好进行更改),我现在想返回“日期" 对于数据库中存在之前的数据,作为建立日期列表的一种方式,我可以在我的 web 页面中显示这些日期,尽管这些天没有数据,但我的图表看起来是一致的。

As an example:举个例子:

  • I want to see the past 30 days of data as a history, but the first 20 days of this period have no data yet, I still need to return the date keys for these days, except with just no data in them.我想查看过去 30 天的数据作为历史记录,但是这段时间的前 20 天还没有数据,我仍然需要返回这些天的日期键,除了其中没有数据。

My current code is as follows (I'm using Carbon):我当前的代码如下(我使用的是 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');
});

Even though there would be no entries to display a "checked_at" column, can this be spoofed with the date for that day with no data?即使没有显示“checked_at”列的条目,这是否可以在没有数据的情况下用当天的日期进行欺骗?

Update 03/05 @ 20:30更新 03/05 @ 20:30

I've updated my description to reflect the latest attempt to solve this problem, I appear to have constructed what I need, however, have some issues:我更新了我的描述以反映解决此问题的最新尝试,我似乎已经构建了我需要的东西,但是有一些问题:

  1. Where I'm looping over my $dates is there a way to build up some structure within each item so I don't have to do if/else checks on all my variables and keys?我在$dates上循环的地方有没有办法在每个项目中建立一些结构,这样我就不必对所有变量和键进行if/else检查?
  2. For some reason, the "fake" dummy dates are being added after the real data, eg: 1st Jan, 2nd Jan, 30th Dec... how can I reverse this?出于某种原因,在真实数据之后添加了“假”虚拟日期,例如:1 月 1 日、1 月 2 日、12 月 30 日……我该如何扭转这种情况?

One way to achieve this is by creating a collection of the dates for the time period you want, and then merging the results of a query grouped by date into it.实现此目的的一种方法是创建所需时间段的日期集合,然后将按日期分组的查询结果合并到其中。

Here's an example:这是一个例子:


$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]

This assumes you are casting the checked_at field to a date in your UptimeChecks Model.这假设您将checked_at字段转换为UptimeChecks Model 中的日期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM