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

P81CFM's avatar

Presenting records in a view group by Year of a mySql date field

Hi guys,

I'm in the process of developing a page which will show the records group by Year (the year will be part of a date field in mySql).

So I will have the year 2018 and below all the records selected where the year of the date field is 2018 then 2017 and so on according to the year available (some year might skip)

I'd like to know what would be the best practice to obtain something like this. Do I have to group the records by Year or simply select the record and then in the View manipulate the object in order to obtain the result? I think I could do it in a very "rustic" way I'm quite confident that there are some techniques in Laravel/Model that could make the entire process much more elegant.

Thanks a lot

0 likes
10 replies
cms007's avatar

Please try like this:

$res = ModelName::where('someColumn', 'test')
    ->get()
    ->groupBy(function ($val) {
        return Carbon::parse($val->created_at)->format('Y');
});
P81CFM's avatar

I printed the content of the object and it retrieved apparently the correct information. In the View I now faced the problem that I cannot use the fields that I selected in the query.

$res= News::select('id', 'language', 'title', 'idcountry', 'idcountry2', 'idcountry3', 'idcountry4', 'idcountry5', 'title_slug', 'category1', 'category2', 'category3', 'created_at', 'str_code', 'date_news')
                 ->where('language', '=', $language)
                 ->where(function ($query) use ($id_country) {
                      $query->orWhere('idcountry', '=', $id_country)
                            ->orWhere('idcountry2', '=', $id_country)
                            ->orWhere('idcountry3', '=', $id_country)
                            ->orWhere('idcountry4', '=', $id_country)
                            ->orWhere('idcountry5', '=', $id_country);
                  })
                ->orderBy('date_news', 'desc')
                ->get()
                ->groupBy(function ($val) {
                    return Carbon::parse($val->date_news)->format('Y');
                });
return view('admin.news.v.group-by-year', 
            compact('list_news')); 

in the View I try to print the content with a foreach loop

@foreach ($list_news as $last)
    <tr><td>{{ $last->title_slug }}</td></tr>
@endforeach 

But I received an error

Property [title_slug] does not exist on this collection instance

Any idea why I received this error and how can I print the records group by Year?

realrandyallen's avatar

the variable list_news doesn't exist, compact takes an existing variable and makes an array out of it's name and values

http://php.net/manual/en/function.compact.php

return view('admin.news.v.group-by-year',  compact('list_news')); 

should be

return view('admin.news.v.group-by-year',  compact('res')); 

and then in your view

@foreach ($res as $last)
    <tr><td>{{ $last->title_slug }}</td></tr>
@endforeach 
P81CFM's avatar

I modified the code as you recommended but I still receive the same error

realrandyallen's avatar

In your foreach loop dump $last and see if it’s what you’re expecting - post the results here as well if you want

P81CFM's avatar

I dump $last

Collection {#331 ▼
  #items: array:17 [▶]
}

If I expand the #items array I can see the "attributes" and "original" containing all the data that I selected in the query

'id', 'language', 'title', 'idcountry', 'idcountry2', 'idcountry3', 'idcountry4', 'idcountry5', 'title_slug', 'category1', 'category2', 'category3', 'created_at', 'str_code', 'date_news'

How can I access the single field?

realrandyallen's avatar

@P81CFM - Looks like $last is another collection so you'll have to loop through it as well to access title_slug

@foreach ($res as $news)
     @foreach ($news as $article)
          <tr><td>{{ $article->title_slug }}</td></tr>
     @endforeach    
@endforeach 
P81CFM's avatar

Thank you so much with your last code I can access title_slug and the other fields.

Now there is just one other question, considering that I would like to have something like this

2018
   news 1
   news 2
   news 3
2017
   news x
   news y
....
1999
   news z

how can I obtain this result?

realrandyallen's avatar
Level 44

@P81CFM - The answer by @cms007 grouped your results by year so it should already be in the format you want...you may just need to change your loop to this:

@foreach ($res as $year => $news)
     <h1>{{ $year }}</h1>
     <table>
          @foreach ($news as $article)
               <tr><td>{{ $article->title_slug }}</td></tr>
          @endforeach    
     </table>
@endforeach 
P81CFM's avatar

Perfect!

Thank you so much

1 like

Please or to participate in this conversation.