Grouping Data in Laravel using Group by function

Grouping data by some specific conditions are commonly required to reduce load time. Grouping data is the concept of SQL but laravel provides an effective way to group data into nested collection objects instead of row-level data.

Let's take an example to perform group by using date.

Creating model and migration

Here, we will create a posts table that has publish date and perform further logic based on that column. Open a terminal and enter the below command:


php artisan make:model Post -m

Above command will create a model and migration file for posts. Let's modify each file one by one. Open App\Models\Post.php and modify below:


<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Test extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'title',
        'slug',
        'content',
        'publish_date'
    ];

    protected $casts = [
        'publish_date'  =>  'date',
    ];
}

Here, we have defined title, slug, content, and publish date columns in the Post model. We have also casts publish_date as a date.

Let's modify migration file as post model.


<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('slug');
            $table->text('content');
            $table->text('content');
            $table->date('publish_date');
            $table->softDeletes();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Let's create a seeder and factory to seed dummy data. Open a terminal and enter the below command:


php artisan make:factory PostFactory

Open database/factories/PostFactory.php file and modify as below:


<?php

namespace Database\Factories;

use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    public function definition()
    {
        return [
            'title'         =>  $this->faker->sentence(10), 
            'slug'          =>  Str::slug($this->faker->sentence(10)),
            'content'       =>  $this->faker->paragraph(),
            'publish_date'  =>  Carbon::now()->subDays(rand(1,100))->format('Y-m-d')
        ];
    }
}    

Now, let's generate dummy data using the Database Seeder file open the Database/seeders/DatabaseSeeder.php file and enter the below code into the run() method.


\App\Models\Post::factory(100)-<create();

Open the terminal and enter the below command into terminal to create a post table and seed data into it:


php artisan migrate

php artisan db:seed

Performing Group By On Date In Laravel

Now our database table is created and we have also completed database seeding into the posts table. so we can perform our queryies.

First of all let's perform day-wise data grouping of the current month's data.


$posts = \App\Models\Post::whereMonth('publish_date', Carbon::now('m'))
    ->get()
    ->groupBy(function($data){
        return $data->publish_date->format('d');
    });

In the above example, we have added a condition to get only the current month's data. and then we grouped data day-wise using the groupBy() function with the callback function. The output of this query will have current month's all data and those data will return collection with the day as key and the value will be recorded on that day.

Let's take another example where we will group data by month. Here we will just modify return date format function like this:


$posts = \App\Models\Post::whereMonth('publish_date', Carbon::now('m'))
    ->get()
    ->groupBy(function($data){
        return $data->publish_date->format('m');
    });

Here, we can also set grouping by month and year too or even by time if we have a date and time column.

Conclusion

In this article, created a posts table and seeded dummy data into that to perform different types of groups by queries on the date column.


Share your thoughts

Ask anything about this examples