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());