Php Laravel-从数据库中填写缺失的日期和计数

Php Laravel-从数据库中填写缺失的日期和计数,php,mysql,eloquent,laravel-5.2,Php,Mysql,Eloquent,Laravel 5.2,我需要根据从$request获取的日期发送每个日期的视图数。从我在controller中的查询中,我得到如下图表的数据: [{"time":"2016-05-01","count":2},{"time":"2016-05-02","count":3},{"time":"2016-05-03","count":7},{"time":"2016-05-07","count":3}] 对于这些数据,我需要添加缺少的日期和0的视图计数。我试图遵循,但我似乎无法为我的示例实现此解决方案。这是我的方法:

我需要根据从
$request
获取的日期发送每个日期的视图数。从我在controller中的查询中,我得到如下图表的数据:

[{"time":"2016-05-01","count":2},{"time":"2016-05-02","count":3},{"time":"2016-05-03","count":7},{"time":"2016-05-07","count":3}]
对于这些数据,我需要添加缺少的日期和
0
的视图计数。我试图遵循,但我似乎无法为我的示例实现此解决方案。这是我的方法:

public function timelines(Request $request){
    $from = $request['from'];
    $to = $request['to'];


    $data = DB::table($request['option'])
                ->select(DB::raw('DATE(created_at) as time'), DB::raw('count(*) as count'))
                ->whereDate('created_at', '>=', date($from).' 00:00:00')
                ->whereDate('created_at', '<=', date($to).' 00:00:00')
                ->groupBy('time')
                ->get();


    return json_encode($data);
  }

您可以循环查看所有要显示的日期,并在while循环中对其进行计数:

public function timelines(Request $request){
    $from = $request['from'];
    $to = $request['to'];
    $date = $from;
    $data = array();

    while($date <= $to) {

        $formattedDate = date('Y-m-d', $date);

        $results = DB::table($request['option'])
                   ->select(DB::raw('count(*) as count'))
                   ->whereDate('created_at', '=', $formattedDate .' 00:00:00')
                   ->groupBy('time')
                   ->get();

        if(count($results)) {
            $data[] = [
                'time' => $formattedDate, 
                'count' => $results[0]->count
            ];
        } else {
            $data[] = [
                'time' => $formattedDate, 
                'count' => 0
            ];
        }

        $date = strtotime('+1 day', $date);
    }

    return json_encode($data);
}
公共功能时间表(请求$Request){
$from=$request['from'];
$to=$request['to'];
$date=$from;
$data=array();
而($date select(DB::raw('count(*)as count'))
->whereDate('created_at','=',$formattedDate.'00:00')
->groupBy(“时间”)
->get();
如果(计数($结果)){
$data[]=[
“时间”=>$formattedDate,
“计数”=>$results[0]->count
];
}否则{
$data[]=[
“时间”=>$formattedDate,
“计数”=>0
];
}
$date=strottime(“+1天”,$date);
}
返回json_encode($data);
}

这个解决方案适合我,我首先创建了一个数组,其中包含时间范围内的所有日期,日期设置为键,计数值设置为0,然后用查询中的计数值替换同一数组中DB中查询后的值:

$period = new DatePeriod( new DateTime($from), new DateInterval('P1D'), new DateTime($to));
      $dbData = [];

      foreach($period as $date){
          $range[$date->format("Y-m-d")] = 0;
      }

      $data = DB::table($request['option'])
                ->select(DB::raw('DATE(created_at) as time'), DB::raw('count(*) as count'))
                ->whereDate('created_at', '>=', date($from).' 00:00:00')
                ->whereDate('created_at', '<=', date($to).' 00:00:00')
                ->groupBy('time')
                ->get();

      foreach($data as $val){
        $dbData[$val->time] = $val->count;
      }

      $data = array_replace($range, $dbData);
    }

    return json_encode($data);
$period=new DatePeriod(new DateTime($from)、new DateInterval('P1D')、new DateTime($to));
$dbData=[];
foreach($期间为$日期){
$range[$date->格式(“Y-m-d”)]=0;
}
$data=DB::table($request['option']))
->选择(DB::raw('DATE(created_at)as time'),DB::raw('count(*)as count'))
->其中日期('created_at','>=',日期($from)。'00:00:00')

->whereDate('created_at',')@Marco回答得很好,但我想做一点改进。不需要调用
array_replace
,而是可以在一个循环中这样做。就像这样

$period = new DatePeriod( new DateTime($from), new DateInterval('P1D'), new DateTime($to));
$dbData = [];

foreach($period as $date){
    $range[$date->format("Y-m-d")] = 0;
}

$data = DB::table($request['option'])
                ->select(DB::raw('DATE(created_at) as time'), DB::raw('count(*) as count'))
                ->whereDate('created_at', '>=', date($from).' 00:00:00')
                ->whereDate('created_at', '<=', date($to).' 00:00:00')
                ->groupBy('time')
                ->get();

foreach($data as $val){
    $range[$val->time] = $val->count; //Filling value in the array
}

//$data = array_replace($range, $dbData); <-- No need to do this.

return json_encode($range);
$period=new DatePeriod(new DateTime($from)、new DateInterval('P1D')、new DateTime($to));
$dbData=[];
foreach($期间为$日期){
$range[$date->格式(“Y-m-d”)]=0;
}
$data=DB::table($request['option']))
->选择(DB::raw('DATE(created_at)as time'),DB::raw('count(*)as count'))
->其中日期('created_at','>=',日期($from)。'00:00:00')

->whereDate('created_at',”Maro和Rutvij Kothari提供的答案是正确的,这里是相同逻辑的更优雅/简化版本

我没有使用两个单独的for循环,而是使用array_map函数来完成相同的操作

$data = DB::table($request['option'])
    ->select(DB::raw('DATE(created_at) as time'), DB::raw('count(*) as count'))
    ->whereDate('created_at', '>=', date($from).' 00:00:00')
    ->whereDate('created_at', '<=', date($to).' 00:00:00')
    ->groupBy('time')
    ->get()
    ->keyBy('time');

$range = array_map(function ($e) use ($data) {
    $date = Carbon::parse($e)->format('Y-m-d');
    return empty($data[$date]) ? 0 : $data[$date]->count;
}, CarbonPeriod::create(Carbon::parse($from), Carbon::parse($to))->toArray());


return json_encode($range);

[{“time”:“2016-03-16”,“count”:0}]
->当您有
$request['option']=='time'
$request['option']!='time'
时,会出现这种情况吗!='time',但我已经想出了一个解决方案,它工作得很好,我设置它的方式。当你可以在集合上循环时,为什么要循环查询,这是一个非常糟糕的问题method@JimmyObonyoAbor是的,你是对的。它根本没有优化。我试着给他一个快速有效的例子,让他走,而不是被卡住。这个我这是一个更有效和更干净的解决方案。嗨,我想使用相同的查询,但有更多的值,然后只计算,我需要做什么更新?
$period = new DatePeriod( new DateTime($from), new DateInterval('P1D'), new DateTime($to));
$dbData = [];

foreach($period as $date){
    $range[$date->format("Y-m-d")] = 0;
}

$data = DB::table($request['option'])
                ->select(DB::raw('DATE(created_at) as time'), DB::raw('count(*) as count'))
                ->whereDate('created_at', '>=', date($from).' 00:00:00')
                ->whereDate('created_at', '<=', date($to).' 00:00:00')
                ->groupBy('time')
                ->get();

foreach($data as $val){
    $range[$val->time] = $val->count; //Filling value in the array
}

//$data = array_replace($range, $dbData); <-- No need to do this.

return json_encode($range);
$data = DB::table($request['option'])
    ->select(DB::raw('DATE(created_at) as time'), DB::raw('count(*) as count'))
    ->whereDate('created_at', '>=', date($from).' 00:00:00')
    ->whereDate('created_at', '<=', date($to).' 00:00:00')
    ->groupBy('time')
    ->get()
    ->keyBy('time');

$range = array_map(function ($e) use ($data) {
    $date = Carbon::parse($e)->format('Y-m-d');
    return empty($data[$date]) ? 0 : $data[$date]->count;
}, CarbonPeriod::create(Carbon::parse($from), Carbon::parse($to))->toArray());


return json_encode($range);
CarbonPeriod::create(Carbon::now()->subDays(7), Carbon::now());