Como criar consultas com múltiplas condições WHERE no Laravel Eloquent
Você já se pegou pensando: "Preciso filtrar registros por três condições diferentes, mas a sintaxe do Eloquent é meio confusa"? Se sim — você não está sozinho. A pergunta "How to Create Multiple Where Clause Query Using Laravel Eloquent?" no Stack Overflow acumulou milhares de visualizações, e não é surpresa. Trabalhar com banco de dados é o coração de qualquer aplicação PHP, e saber construir consultas complexas diferencia um iniciante de um profissional.
Neste artigo, vamos abordar todas as formas de criar múltiplas condições WHERE no Laravel Eloquent: desde as cadeias mais simples até construções lógicas aninhadas. Você aprenderá como combinar AND e OR, usar whereHas para modelos relacionados e evitar erros típicos. Vamos lá!
Sintaxe básica: encadeamento de WHERE
A forma mais óbvia de adicionar várias condições é simplesmente chamar where() várias vezes seguidas. Por padrão, todas as condições são unidas por AND.
// Obter todos os usuários com status = 'active' E role = 'admin'$users = User::where('status', 'active') ->where('role', 'admin') ->get();
// SQL equivalente:// SELECT * FROM users WHERE status = 'active' AND role = 'admin'Você pode passar um array de condições:
$users = User::where([ ['status', '=', 'active'], ['role', '=', 'admin'],])->get();Ambas as opções funcionam, mas a primeira é mais legível, especialmente quando há muitas condições.
Condição OR: quando precisamos de "ou"
E se precisarmos encontrar usuários que OU são ativos OU são administradores? É aí que entra o orWhere().
// Usuários com status = 'active' OU role = 'admin'$users = User::where('status', 'active') ->orWhere('role', 'admin') ->get();
// SQL: SELECT * FROM users WHERE status = 'active' OR role = 'admin'⚠️ Aviso importante: Se você misturar where e orWhere, lembre-se da precedência dos operadores. O Laravel os processa sequencialmente, então o resultado pode ser diferente do esperado.
Exemplo com pegadinha
// Queremos: (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'// Isso NÃO é a mesma coisa!Para obter o resultado correto, use agrupamento com 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'WHERE aninhados: agrupamento de condições
Quando a lógica fica mais complexa, os closures aninhados vêm em socorro. Esta é a ferramenta mais poderosa para criar condições complexas.
// (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();O código se lê como um livro: "encontre usuários que são maiores de idade e ativos, OU menores de idade com aprovação dos pais".
Condições com operadores: WHERE IN, BETWEEN, NULL
O Eloquent suporta todos os operadores SQL padrão. Aqui estão alguns úteis:
whereIn — verificação de pertencimento a uma lista
<