Hello Folks , i'm using laravel charts to get some data from databse for last month , so the for loop checkeng each day if there a data or not , i can't find a way to get the same result with less queries , so like images there more than 60 query for 2 charts , so is there any other way to get result with less queries ??
public function index()
{
// GET NUMBER CLAIMS EACH DAY FOR A MONTH
$dataOneMonth = collect([]);
for ($days_backwards = 30; $days_backwards > 0; $days_backwards--) {
$dataOneMonth->push(
Claim::whereDate('created_at', today()->subDays($days_backwards))->count()
);
}
$claimsInMonth = new ClaimsChart;
$claimsInMonth->labels($dataOneMonth->keys());
$claimsInMonth->dataset('Claim', 'line', $dataOneMonth->values());
$claimsInMonth->title("Number of claims this month");
$claimsInMonth->datasets[0]->backgroundColor(['#FFC300']);
// TRACK DEAD CLAIMS each day in a month via audits table
$dataOneMonth1 = collect([]);
for ($days_backwards = 30; $days_backwards > 0; $days_backwards--) {
$dataOneMonth1->push(
Audit::select()
->where([['auditable_type', 'App\Claim']])
->whereRaw('JSON_CONTAINS(`new_values`, \'{"status_id":"dead"}\')')
->whereDate('created_at', today()->subDays($days_backwards))
->count()
);
}
$chart2 = new ClaimsChart;
$chart2->labels($dataOneMonth1->keys());
$chart2->dataset('Claim', 'line', $dataOneMonth1->values());
$chart2->title("Number of dead claims this month");
return view('reports.index', compact('claimsInMonth', 'chart2'));
}
You're creating 60 queries where you can have two. I'll demonstrate how to shorten the query for the first collection:
$dataOneMonth = Claim::whereBetween('created_at', [today(), today()->subMonth()]) //get all records in that timespan
->groupBy(DB::raw('DATE(created_at)')) //unify the day they've been created on as a date, so that we can group
->orderBy('created_at') //order by creation
->get() //retrieve the collection of claims, at this point we're having a collection of 'date' => $claims
->map(function($claims){
return $claims->count(); //for each collection of claims for a given day, return its count
});
So now $dataOneMonth should be like 'date' => $count. Not tested, improvised, may need a redaction here or there, but you get the point.
thinks i did like you said but it getting only days that new record had add , not the all month
$thisMonth = \Carbon\Carbon::today();
$oneMonthAgo = \Carbon\Carbon::today()->subMonth();
$dateRange = [$oneMonthAgo, $thisMonth];
$dataOneMonth = Claim::whereBetween('created_at', $dateRange) //get all records in that timespan
->groupBy(\DB::raw('DATE(created_at)')) //unify the day they've been created on as a date, so that we can group
->orderBy('created_at') //order by creation
->get() //retrieve the collection of claims, at this point we're having a collection of 'date' => $claims
->map(function ($claims) {
return $claims->count(); //for each collection of claims for a given day, return its count
});
dd($dataOneMonth);
Didn't get what you said. Could be that I've misunderstood your exact needs, but regarding the queries that's your solution for one instead of 30 queries. You can then modify the collection however it suits your needs.