Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dirkolbrich's avatar

How to group Collection with daily dates yyyy-mm-dd by month and/or years?

Hi, I have an Eloquent collection with a lot of items. Each item has an attribute ´$item->date = yyyy-mm-dd´, which is a date. Each of these attributes is an underlying ´date´ field in the database as well. I use PostgreSQL as my database.

How can I sort this collection by month ´yyyy-mm´ or years ´yyyy´?

Each of these ´$item´ has a ´$item->value = xxxx´. I want to find the highest an lowest value of each month/year.

Could you point me into a direction? Thanks.

0 likes
5 replies
dirkolbrich's avatar
dirkolbrich
OP
Best Answer
Level 1

Nevermind, I usually find the solution, AFTER I ask.

$weeklyQuotes = $quotes->groupBy(function($item) {
    return Carbon::createFromFormat('Y-m-d', $item->date)->format('Y-W');
 });
$monthlyQuotes = $quotes->groupBy(function($item) {
    return Carbon::createFromFormat('Y-m-d', $item->date)->format('Y-m');
});
$yearlyQuotes = $quotes->groupBy(function($item) {
    return Carbon::createFromFormat('Y-m-d', $item->date)->format('Y');
});
1 like
JarekTkaczyk's avatar

@dirkolbrich

$collection->groupBy(function ($item) {
  return $item->date->format('Y-m'); // given date is mutated to carbon by eloquent..
  return (new \DateTime($item->date))->format('Y-m'); // ..othwerise
})->reduce(function ($result, $group) {
  return $result->put($group->first()->date->format('Y-m'), collect([
    'min' => $group->min('value'),
    'max' => $group->max('value'),
  ]));
}, collect());

// you get something like this:
Illuminate\Support\Collection {#873
     all: [
       "2015-10" => Illuminate\Support\Collection {#870
         all: [
           "min" => 1
           "max" => 1
         ]
       }
       "2015-07" => Illuminate\Support\Collection {#1002
         all: [
           "min" => 123
           "max" => 126
         ]
       }
       "2015-05" => Illuminate\Support\Collection {#865
         all: [
           "min" => 21
           "max" => 122
         ]
       }
       "2015-03" => Illuminate\Support\Collection {#1003
         all: [
           "min" => 2
           "max" => 20
         ]
       }
     ]
   }

Mind that with high volume of these items, you may want to use sql instead, since collection methods are slower.

1 like
dirkolbrich's avatar

Ah, sorting by date and fetching min/max values in one query sounds interesting. Thanks for the hint, will test it.

RobBiermann's avatar

Why would you ask if you already know the answer anyway?

Cruorzy's avatar

@robbiermann Pretty sure he has moved on after 4 years... Also he found it AFTER he asked the question. It's litterly in the Green answer area.

According to the 1027 views on the page, he must have helped some people even with his own answer :)

Please or to participate in this conversation.