How to Create Queries with Multiple WHERE Conditions in Laravel Eloquent
Have you ever caught yourself thinking: "I need to filter records by three different conditions, but the Eloquent syntax is somehow confusing"? If so — you are not alone. The question "How to Create Multiple Where Clause Query Using Laravel Eloquent?" on Stack Overflow has gathered thousands of views, and it's no surprise. Working with a database is the heart of any PHP application, and the ability to build complex queries distinguishes a beginner from a professional.
In this article, we will cover all the ways to create multiple WHERE conditions in Laravel Eloquent: from the simplest chains to nested logical constructs. You will learn how to combine AND and OR, use whereHas for related models, and avoid common mistakes. Let's go!
Basic Syntax: WHERE Chain
The most obvious way to add multiple conditions is to simply call where() several times in a row. By default, all conditions are joined with AND.
// Get all users where status = 'active' AND role = 'admin'$users = User::where('status', 'active') ->where('role', 'admin') ->get();
// Equivalent SQL:// SELECT * FROM users WHERE status = 'active' AND role = 'admin'You can pass an array of conditions:
$users = User::where([ ['status', '=', 'active'], ['role', '=', 'admin'],])->get();Both options work, but the first one is easier to read, especially when there are many conditions.
OR Condition: When You Need "Or"
But what if we need to find users who are EITHER active OR are administrators? This is where orWhere() comes into play.
// Users where status = 'active' OR role = 'admin'$users = User::where('status', 'active') ->orWhere('role', 'admin') ->get();
// SQL: SELECT * FROM users WHERE status = 'active' OR role = 'admin'⚠️ Important caveat: If you mix where and orWhere, remember operator precedence. Laravel processes them sequentially, so the result may differ from what you expect.
Example with a Pitfall
// We want: (status = 'active' AND role = 'admin') OR (plan = 'premium')$users = User::where('status', 'active') ->where('role', 'admin') ->orWhere('plan', 'premium') ->get();
// SQL: WHERE status = 'active' AND role = 'admin' OR plan = 'premium'// This is NOT the same!To get the correct result, use grouping with a closure:
$users = User::where(function ($query) { $query->where('status', 'active') ->where('role', 'admin');})->orWhere('plan', 'premium') ->get();
// SQL: WHERE (status = 'active' AND role = 'admin') OR plan = 'premium'Nested WHERE: Grouping Conditions
When the logic becomes more complex, nested closures come to the rescue. This is the most powerful tool for creating complex conditions.
// (age > 18 AND status = 'active') OR (age <= 18 AND parent_approved = 1)$users = User::where(function ($query) { $query->where('age', '>', 18) ->where('status', 'active');})->orWhere(function ($query) { $query->where('age', '<=', 18) ->where('parent_approved', 1);})->get();The code reads like a book: "find users who are adults and active, OR minors with parental approval".
Conditions with Operators: WHERE IN, BETWEEN, NULL
Eloquent supports all standard SQL operators. Here are a few useful ones:
whereIn — Check for Inclusion in a List
<