Laravel using where clause on a withCount method

Stefan Izdrail

Founder & Senior Architect · 2026-06-29

Laravel Company

Laravel's withCount() method helps in retrieving related models along with their counts by eagerly loading them without requiring extra queries. However, you might encounter issues when attempting to filter these results using a where clause on the count result. In this comprehensive blog post, we will explore various techniques to solve this issue with code examples and explanations.

Technique 1: Use Eloquent Relationships

One approach is to use Laravel's built-in relationships between models. Let's say you have a Post model that has many Upvotes (belongsToMany relationship), as shown below:
class Post extends Model {
    public function upvotes() {
        return $this->belongsToMany(\App\Upvote::class);
    }
}
Now, you can use the upvotes relationship to get all posts with more than five upvotes:
$posts = Post::withCount('upvotes')->whereHas('upvotes', function($query) {
    $query->whereRaw('upvoteable_count > 5');
})->get();
The query above will return all posts that have more than five upvotes. This method works because it performs the withCount() operation first, then applies the whereHas() scope to filter the results based on the count of related records.

Technique 2: Leverage Raw SQL

Another option is to use Laravel's query builder to run a custom raw SQL statement that includes both the count and where clauses in the same query. Here's an example using the same Post and Upvote models and the related relationship:
$sql = "SELECT posts.*, COUNT(upvotes.id) AS upvotes_count FROM posts LEFT JOIN upvotes ON upvotes.upvoteable_type = 'App\Post' AND upvotes.upvoteable_id = posts.id GROUP BY posts.id HAVING upvotes_count > 5";
$posts = DB::select($sql);
The query above filters posts that have more than five upvotes. However, since it is a raw SQL query, you might lose the benefits of Laravel's Eloquent models and relationships. Be cautious when using this method.

Technique 3: Use Multiple Queries

As a last resort, you can retrieve all posts with at least one upvote and then filter those results by the count of upvotes in code:
$posts = Post::withCount('upvotes')->get();
foreach ($posts as $post) {
    if ($post->upvotes_count > 5) {
        // Append filtered posts to an array or collection
    }
}
This approach involves two queries: one for getting all posts with upvotes and another for filtering the results. It can be more efficient if you only need a small subset of posts that have more than five upvotes. However, it may not scale well as the number of records grows since each post is processed individually. In conclusion, handling where clauses on count() methods in Laravel can be challenging. The most efficient solutions depend on your specific needs and database structure. Choose an approach that best suits your situation, ensuring a balance between performance, code clarity, and maintainability.