How to Use GroupBy with Pagination in Laravel 12

How to Use GroupBy with Pagination in Laravel 12

How to Use GroupBy with Pagination in Laravel 12 (Complete Tutorial)

When working with large datasets in Laravel applications, grouping and paginating results efficiently can be challenging. The GroupBy function helps you organize records based on specific columns, while pagination keeps your results clean and manageable.

In this tutorial, we’ll explore how to combine GroupBy with pagination in Laravel 12, using real-world examples, optimized queries, and clean Eloquent syntax.

🔍 Why Use GroupBy with Pagination?

The groupBy() method in Laravel (based on SQL’s GROUP BY) allows you to aggregate data—like counting orders by customers, listing posts by categories, or summarizing transactions by date.

Pagination ensures performance and usability, especially when you’re working with hundreds or thousands of grouped results.

Example use cases:

  • Count total orders grouped by customer
  • Display user activity grouped by date
  • List articles grouped by author

⚙️ Setting Up Your Laravel 12 Project

Before diving into the code, make sure your environment is ready.


composer create-project laravel/laravel laravel12-groupby-demo
cd laravel12-groupby-demo
php artisan serve

Once your Laravel app is running, set up a database connection inside your .env file:


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=groupby_demo
DB_USERNAME=root
DB_PASSWORD=

Run migrations:


php artisan migrate

Step 1: Create an Eloquent Model


php artisan migrate

In the Order.php model, make sure your fillable fields are defined:


namespace App\Models;

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

class Order extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'total_amount',
    ];
}

Step 2: Insert Dummy Data

You can use Laravel seeders to generate sample data:


php artisan make:seeder OrderSeeder

Edit database/seeders/OrderSeeder.php:


namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Order;

class OrderSeeder extends Seeder
{
    public function run()
    {
        Order::factory()->count(50)->create();
    }
}

Then run:


php artisan db:seed --class=OrderSeeder

🔧 Step 3: Implement GroupBy with Pagination

Here’s where the magic happens.

Open your OrderController.php and add the following code:


namespace App\Http\Controllers;

use App\Models\Order;
use Illuminate\Support\Facades\DB;

class OrderController extends Controller
{
    public function index()
    {
        $orders = DB::table('orders')
            ->select('user_id', DB::raw('COUNT(*) as total_orders'), DB::raw('SUM(total_amount) as total_spent'))
            ->groupBy('user_id')
            ->paginate(10); // 10 groups per page

        return view('orders.index', compact('orders'));
    }
}

🔧 Step 3: Implement GroupBy with Pagination

Create a view file at: resources/views/orders/index.blade.php





    Laravel 12 GroupBy with Pagination
    



<div class="container">
    <h2 class="mb-4 text-center">Orders Grouped by User</h2>

    
            @foreach($orders as $order)
                
            @endforeach
        <table class="table table-bordered table-striped">
        <thead class="table-dark">
            <tr>
                <th>User ID</th>
                <th>Total Orders</th>
                <th>Total Amount Spent</th>
            </tr>
        </thead>
        <tbody><tr>
                    <td>{{ $order->user_id }}</td>
                    <td>{{ $order->total_orders }}</td>
                    <td>${{ number_format($order->total_spent, 2) }}</td>
                </tr></tbody>
    </table>

    <div class="d-flex justify-content-center">
        {!! $orders->links() !!}
    </div>
</div>




🧮 Step 5: Add Route

Add this line in routes/web.php:


use App\Http\Controllers\OrderController;

Route::get('/orders', [OrderController::class, 'index']);

Now visit:

👉 http://127.0.0.1:8000/orders

You’ll see all your grouped user orders neatly paginated.

⚡ Bonus: Using Eloquent Instead of Query Builder

If you prefer Eloquent for cleaner syntax:


$orders = Order::select('user_id', DB::raw('COUNT(*) as total_orders'), DB::raw('SUM(total_amount) as total_spent'))
    ->groupBy('user_id')
    ->paginate(10);

Same output — just more “Laravel-ish” and readable.

🔄 Common Mistake: GroupBy with ->get() Only

If you use ->get() instead of ->paginate(), you’ll fetch all grouped results at once.

That works fine for small tables, but it’s inefficient for large data sets.

Always use pagination for better memory optimization and performance.

📘 Real-Life Example: GroupBy with Relationship

Let’s say each order belongs to a user (via belongsTo relationship):


public function user()
{
    return $this->belongsTo(User::class);
}

You can group and fetch related user names like this:


$orders = Order::with('user:id,name')
    ->select('user_id', DB::raw('SUM(total_amount) as total_spent'))
    ->groupBy('user_id')
    ->paginate(10);

Then in your Blade:


{{ $order->user->name }}
${{ $order->total_spent }}

🏁 Conclusion

Combining GroupBy with pagination in Laravel 12 allows you to create powerful, scalable dashboards and reports without compromising performance.

It’s especially useful in:

  • Analytics dashboards
  • Sales reports
  • User activity summaries

Laravel’s fluent syntax and pagination features make it simple to build efficient queries while keeping your code elegant and easy to maintain.

Frequently Asked Questions


1. What is the use of GroupBy in Laravel?

GroupBy in Laravel helps organize records based on one or more columns, similar to SQL’s GROUP BY. It’s commonly used for summarizing data such as totals, counts, or averages.

2. Can I use pagination with GroupBy in Laravel?

Yes, Laravel supports pagination on grouped queries using paginate() with both Query Builder and Eloquent. It allows you to manage large grouped datasets efficiently.

3. How do I count records per group in Laravel 12?


DB::table('orders')
    ->select('user_id', DB::raw('COUNT(*) as total_orders'))
    ->groupBy('user_id')
    ->paginate(10);

4. Does pagination work with complex joins and groupBy in Laravel?

Yes. Laravel’s Query Builder and Eloquent ORM support joins, aggregates, and groupBy together — as long as your selected fields are compatible with SQL group rules.

Do you accept cookies?

We use cookies to enhance your browsing experience. By using this site, you consent to our cookie policy.

More