Laravel Eloquent: sum with groupBy
Stefan Izdrail
Founder & Senior Architect · 2026-06-29
Title: Efficiently Sum and Group Data Using Laravel Eloquent Queries - A Comprehensive Guide
When it comes to handling large datasets in your application, Laravel's Eloquent ORM allows you to perform complex queries efficiently. However, sometimes, you may need to calculate the sum of a column while grouping by another column. In this blog post, we will explore how to achieve this goal using Laravel's eloquent query builder.
Grouping and Summing with Eloquent Queries
To get started, let's consider a simple example where you want to display the total number of pages in your application for each user. You have two tables: 'users', which contains basic user information, and 'documents', which stores documents uploaded by users. Both tables are related by their 'user_id' column. $users = User::withCount([
'documents' => function ($query) {
$query->selectRaw('COUNT(*) as no_of_pages')
->groupBy('users_editor_id');
},
])->get();
In this example, you use Laravel's Eloquent relationships to count the number of documents belonging to each user. Firstly, define an inner relationship that counts the total number of pages for each user using a custom query with groupBy. Then, fetch all users and their counts with the 'withCount()' method.
Alternatively, you can use the 'sum()' method when returning values instead of counting:
$users = User::has('documents')->select(['users.*', DB::raw('SUM(documents.no_of_pages) as total_pages')])->groupBy('users.id')->get();
This query joins the 'user' and 'document' tables to obtain the sum of pages per user. However, it requires accessing the database twice, once for each relationship query (counting the number of documents and retrieving all users with their details). A more efficient solution would be to retrieve the data in one query using a subquery:
$users = User::select([
'users.*',
DB::raw('SUM(CASE WHEN (SELECT COUNT(*) FROM documents d WHERE users.id = d.user_id) IS NOT NULL THEN 1 ELSE 0 END * no_of_pages) as total_pages')
])->groupBy('users.id')->get();
In this query, a subquery calculates the count of documents per user and multiplies it by the number of pages present in the 'documents' table before using a 'CASE WHEN' statement to sum them. Although complex, this approach ensures that you only execute one database query for the entire operation.