Getting count from pivot table in laravel eloquent

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Aggregation: Getting Counts from Many-to-Many Relationships in Laravel Eloquent

When working with relational databases, especially those involving many-to-many relationships like orders and products, aggregating data—such as counting how many times a product has been ordered—is a very common requirement. As a senior developer, we often find ourselves needing to translate complex SQL joins into elegant, readable, and maintainable Eloquent code.

The scenario you presented involves a belongsToMany relationship between Product and Order. You want to retrieve a list of products along with the total number of orders associated with each product. While the raw SQL query is powerful, replicating this logic purely through Eloquent relationships offers a much cleaner approach within the Laravel ecosystem.

This guide will show you the most efficient and idiomatic way to fetch these counts using Laravel Eloquent, bypassing the need to manually construct complex joins if possible, demonstrating how Laravel simplifies database interaction.


Understanding the Eloquent Approach: withCount()

The core mechanism for achieving this aggregation in Eloquent is the withCount() method. This method allows you to efficiently fetch a relationship and simultaneously add an aggregated count of related models to the result set. It handles the necessary SQL grouping and counting internally, making your code significantly cleaner than writing raw joins and aggregate functions manually.

To use this effectively, we need to start from the model where we want the counts displayed (in this case, the Product model) and define the relationship correctly.

1. Model Setup Review

First, let's ensure our models are set up as you described:

// app/Models/Order.php
class Order extends Eloquent {
    public function user()
    {
        return $this->belongsTo('User');
    }

    public function products()
    {
        return $this->belongsToMany('Product');
    }
}

// app/Models/Product.php
class Product extends Eloquent {
    public function orders()
    {
        return $this->belongsToMany('Order');
    }
}

Notice that the Product model has a relationship back to Order, which is what we need to count against.

2. Implementing the Count Query

To fetch every product and its corresponding order count, you would apply withCount() on the relationship. Since we want to count the related Orders for each Product, we call it on the orders relationship:

use App\Models\Product;

$productsWithCounts = Product::withCount('orders')->get();

// Example of accessing the results
foreach ($productsWithCounts as $product) {
    echo "Product: " . $product->description . ", Orders Count: " . $product->orders_count . "\n";
}

3. The Result and Performance Benefits

When executed, this Eloquent query translates into an optimized SQL statement that performs a LEFT JOIN and a GROUP BY operation internally, similar to your manual example, but abstracted away by the framework:

SELECT 
    products.*, 
    COUNT(order_product.order_id) AS orders_count 
FROM 
    products
INNER JOIN 
    order_product ON products.id = order_product.product_id
GROUP BY 
    products.id;

The key benefit here is abstraction and readability. Instead of writing complex joins, you use expressive methods like withCount(). This approach aligns perfectly with the principles of building robust applications, much like the architectural focus seen in projects developed by teams focusing on quality code practices, such as those promoted by laravelcompany.com.

Conclusion

Using Eloquent's built-in aggregation methods like withCount() is vastly superior to manually constructing complex SQL queries for simple counting tasks. It keeps your data access logic within the domain of your models, making the code cleaner, more maintainable, and less prone to error. For any intricate data retrieval in Laravel, leveraging these powerful Eloquent features ensures that you write code that is both expressive and highly performant.