2016-05-23 4 views
2

$requestから取得した日付に基づいて、各日付のビュー数を送信する必要があります。私は行方不明の日付と0のビューの数を追加する必要があり、そのデータについてはLaravel - データベースから失われた日付と数を入力してください

[{"time":"2016-05-01","count":2},{"time":"2016-05-02","count":3},{"time":"2016-05-03","count":7},{"time":"2016-05-07","count":3}] 

:コントローラの私のクエリから、私はこのようになりますチャートのデータを取得します。私はthis exampleに従うことを試みているが、私の例ではこの解決策を実装できないようだ。これは私の方法である:

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

更新コード:これにより

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

    if ($request['option'] == 'time'){ 
     $data = View::groupBy('time') 
       ->orderBy('time', 'ASC') 
       ->whereDate('created_at', '>=', date($from).' 00:00:00') 
       ->whereDate('created_at', '<=', date($to).' 00:00:00') 
       ->get([ 
       DB::raw('Hour(created_at) as time'), 
       DB::raw('COUNT(*) as "count"') 
       ]); 
    } 
    else { 
     while($date <= $to) { 
     $formattedDate = date('Y-m-d', strtotime($date)); 

     $results = DB::table($request['option']) 
        ->select(DB::raw('DATE(created_at) as time'), 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', strtotime($formattedDate)); 
     } 
    } 

    return json_encode($data); 
    } 

私は例えば、私が送る最初の日付のカウントを取得:

[{"time":"2016-03-16","count":0}] 
+0

'[{" time ":" 2016-03-16 "、" count ":0}]' $ request ['option'] ==のときに得られる結果です'time' 'または' $ request ['option']!= 'time''? – henrik

+0

私は$ request ['option']!= 'time'を持っているときに起こりますが、私は既に解決策を思いつきました。 – Marco

答えて

1

このソリューションは私にとってはうまくいきました。まず、キーで設定された日付とカウント値が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); 
-1

あなたは可能性がループを通って表示するすべての日付を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); 
} 
+0

あなたの提案で質問を更新しました – Marco

+0

コレクションでループを実行できるときにquerryをループする理由は非常に貧弱です。 –

+0

@JimmyObonyoAborはい、そうです。それはまったく最適化されていません。私は彼に働きかける簡単な例を与えようとしました。 – henrik

0

@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); 
関連する問題