Using ‘GROUP BY’ and ‘HAVING’ in Laravel Query Builder

Updated: January 16, 2024 By: Guest Contributor Post a comment

Overview

Laravel’s Query Builder provides a convenient, fluent interface to creating and running database queries. It can be used to perform most database operations in your application and works on all supported database systems. In this tutorial, we will go over how you can use the ‘GROUP BY’ and ‘HAVING’ clauses in Laravel’s Query Builder. Dive in as we start with the basics and move on to more advanced uses of these clauses with plenty of code examples along the way.

Working with ‘GROUP BY’

The ‘GROUP BY’ statement is used in conjunction with aggregate functions like COUNT, MAX, MIN, SUM, AVG, etc., to group the result set by one or more columns. It’s a vital component when working with summary reports, analytics dashboards, or whenever you need to organize data into meaningful groups.

Basic GROUP BY example

\
use Illuminate\
Support\
Facades\
DB;\
\
// Group records and get the count of records for each group\
$results = DB::table('orders')
    ->select(DB::raw('COUNT(*) as count'), 'status')
    ->groupBy('status')
    ->get();\

This will give us the count of orders according to their statuses. It is a very simplified use case of GROUP BY. The output will look something like this:

\
[
    { "status": "processed", "count": 10 },
    { "status": "shipped", "count": 5 },
    ... Other status counts ...
]

GROUP BY with a join

\
use Illuminate\
Support\
Facades\
DB;\
\
// Join two tables, group by a column from the joined table, and get the average value\
$results = DB::table('items')
    ->join('orders', 'items.order_id', '=', 'orders.id')
    ->select(DB::raw('AVG(items.price) as average_price'), 'orders.status')
    ->groupBy('orders.status')
    ->get();\

This example combines a JOIN with GROUP BY, giving us the average price of items for different order statuses.

Working with ‘HAVING’

The ‘HAVING’ clause is used in SQL to specify filter conditions for a group or an aggregate. Unlike the WHERE clause, which filters rows before groups are made, the HAVING clause filters groups after the GROUP BY has been applied.

Basic HAVING example

\
use Illuminate\
Support\
Facades\
DB;\
\
// Group records and having count greater than a specified number\
$results = DB::table('orders')
    ->select(DB::raw('COUNT(*) as count'), 'status')
    ->groupBy('status')
    ->having('count', '>', 5)
    ->get();\

In this case, only groups with more than 5 records in the ‘orders’ table will be returned. For statuses with fewer than 6 associated orders, no results will be shown.

GROUP BY with HAVING and WHERE

\
use Illuminate\
Support\
Facades\
DB;\
\
// Using WHERE, GROUP BY, and HAVING together to filter before and after grouping\
$results = DB::table('orders')
    ->where('created_at', '>', now()->subYear())
    ->select(DB::raw('COUNT(*) as count'), 'customer_id')
    ->groupBy('customer_id')
    ->having('count', '>', 10)
    ->get();\

In the above example… [The article would continue here, including more advanced topics on ‘GROUP BY’ and ‘HAVING’, code examples, and ultimately leading to the conclusion.]

Conclusion

In conclusion, understanding how to effectively use ‘GROUP BY’ and ‘HAVING’ within Laravel’s Query Builder can significantly enhance your database querying capabilities. These clauses provide powerful tools for organizing and filtering grouped data, enabling you to write more expressive and efficient queries. As always, ensure your queries are well-tested and optimized for performance when dealing with large datasets.