Laravel + Eloquent: How to Group Data by Multiple Columns

Updated: February 22, 2024 By: Guest Contributor Post a comment

Overview

Laravel’s Eloquent ORM provides a fluent and convenient way to interact with your database. When it comes to retrieving and manipulating data, Eloquent offers various methods to achieve complex operations with minimal effort. One such operation is grouping data by multiple columns, a common requirement for reports, analytics, and summaries. This tutorial delves into how to group data by multiple columns using Eloquent, covering from basic to advanced examples.

Understanding Group By in Eloquent

Before diving into the examples, it’s essential to understand what grouping data entails. Grouping data is a way of combining rows that have the same values in specified columns into summary rows. It is often used along with aggregate functions (like COUNT, MAX, MIN, SUM, AVG) to perform operations on grouped data.

Basic Grouping

First, let’s see how to perform a simple group by operation using Eloquent. Assume you have a ‘sales’ table with columns ‘date’, ‘product_id’, and ‘amount’. To group data by ‘product_id’:

$sales = Sale::selectRaw('product_id, SUM(amount) as total_sales')
->groupBy('product_id')
->get();

This query groups the sales by product id and calculates the total sales for each product.

Grouping by Multiple Columns

To group by multiple columns, you can pass multiple arguments to the groupBy method. For example, to group sales by both ‘product_id’ and ‘date’:

$sales = Sale::selectRaw('product_id, date, SUM(amount) as total_sales')
->groupBy('product_id', 'date')
->get();

Here, the sales are grouped by both product id and date, providing a more granular view of sales data.

Advanced Grouping with Having

Sometimes, you might want to filter groups based on a condition. This is where the having clause comes in. For instance, to filter groups by a minimum total sale amount:

$sales = Sale::selectRaw('product_id, SUM(amount) as total_sales')
->groupBy('product_id')
->having('total_sales', '>', 1000)
->get();

This query only returns groups where the total sales exceed 1000. It’s akin to a WHERE condition but applied after grouping.

Grouping by Relation’s Column

In a scenario where you need to group data based on a column of a related model, you can use joins. Assume ‘products’ is a related table with a ‘category_id’ column, and you want to group sales by product category:

$sales = Sale::selectRaw('category_id, SUM(amount) as total_sales')
->join('products', 'sales.product_id', '=', 'products.id')
->groupBy('products.category_id')
->get();

This query joins the ‘sales’ and ‘products’ tables and groups the sales by product category.

Complex Grouping with Raw Expressions

For more complex grouping scenarios, you can use raw expressions. Imagine you want to group sales by the year and month of the date:

$sales = Sale::selectRaw('YEAR(date) as year, MONTH(date) as month, SUM(amount) as total_sales')
->groupByRaw('YEAR(date), MONTH(date)')
->get();

This query groups sales by the year and month, providing insights into monthly sales trends over years.

Conclusion

Laravel’s Eloquent enables easy and efficient data grouping by multiple columns, facilitating complex data retrieval and manipulation operations. By leveraging the techniques discussed in this tutorial, you can extract meaningful insights from your data with minimal code.