I am trying to set up a small statistical module. I am looking for an array containing for each month the number of events of my 'evenement' table. With the query below I get the results but only if there is a result in the month. IF there is none, it does not appear. My request:
$data = DB::table("evenements")
->select(DB::raw('EXTRACT(MONTH FROM datedevenement) AS month, COUNT(id) as id'),
DB::raw('ifnull(count(id),0) as id')
)
->where('typeevenement_id', '1')
->whereYear('datedevenement', Carbon::now()->year)
->orderBy('datedevenement')
->groupBy(DB::raw('month'))
->get();
return $data;
My evenement table :
id | datedevenement | typeevenement_id
I understand that my request can not invent months that do not exist. I wonder if carbon or laravel does not have something to list by month or year in a continuous way.
Result must be an array or collection with monthORyears->count(evenement)
Thanks you. With this 2 answers and a small serach i arrived to this solution (i have add somathing for order with current month for start point) :
$monthly_uploaded_product = Evenement::select(DB::raw('COUNT(id) as total, EXTRACT(MONTH FROM datedevenement) AS month')
)
->where('typeevenement_id', '1')
->wheredate('datedevenement', '>=', Carbon::now()->lastOfMonth()->subyears(1))
/// ->whereYear('datedevenement', Carbon::now()->year)
->groupBy(DB::raw('month'))
->get();
$mois = ["janvier", "fevrier", "mars", "avril", "mai", "juin", "juillet", "aout", "septembre", "octobre", "novembre", "decembre"];
foreach ($mois as $mois99) {
$arriveeparmoisrefuge[]= array(
'mois' => $mois99,
'total' => '0'
);
}
foreach ($monthly_uploaded_product as $key) {
$arriveeparmoisrefuge[$key->month - 1]['total'] = $key->total;//update each month with the total value
}
$sorted = collect($arriveeparmoisrefuge)->sortBy(function ($count, $month) {
$currentMonth = (int) \Carbon\Carbon::now()->month;
return ($month + (13 - $currentMonth - 1)) % 12;
});
return $sorted;
The simplest thing could be to do a foreach of months and conflict it with the collection, if not present add it.
For simplicity you can apply the method keyby() (documentation)
->keyBy('month')
on your collection.
and then perform the foreach like this:
$months =["January", "February", ....];
foreach ($months as $month){
if (!isset($data[$month])){
$data[$month]['id'] = 0;
}
}
I liked Claudio's answer, but I'd try another way.
First, I get a collection of my events:
$temp = $model
->orderBy("date_field")
->get()
->groupBy(function($query) {
return Carbon::parse($query->date_field)
->format("m");
})
Now, you have a collection grouped by month.
My second step was iterate with the collection $temp
like that:
$result = new array();
$temp->each(function($query) use (&$result) {
$result["count"] = $query->count();
$result["data"] = $query;
});
Now, you have an array with a collection to explore your data and a counter to know how much events will be realised per month. When you haven't event it's necessary to sanitizer with your frontend.
Hope that help you.
Reference: https://laraveldaily.com/laravel-group-query-result-by-day-month-year/