Consultas WHERE complejas en Laravel Eloquent: 4 métodos con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cómo construir un WHERE complejo en Laravel Eloquent: 4 métodos con ejemplos

\n\n

Imagina que estás desarrollando una tienda online con Laravel. Necesitas encontrar todos los productos que cuestan entre 1000 y 5000 pesos, están en stock, no pertenecen a la categoría "Oferta" y fueron creados después del 1 de enero de 2024. ¿Cómo hacerlo con una sola consulta sin sacrificar el rendimiento?

\n\n

Esta pregunta es una de las más populares en Stack Overflow (¡miles de visitas!). Y con razón: saber construir condiciones WHERE complejas en Laravel Eloquent marca la diferencia entre un principiante y un desarrollador de producción.

\n\n

En este artículo te mostraré 4 métodos probados para crear condiciones WHERE múltiples. Aprenderás cuándo usar arrays, cuándo usar closures, cómo agrupar condiciones y cómo evitar inyecciones SQL. ¡Vamos allá!

\n\n
\n\n

1. Método básico: array de condiciones (para AND simples)

\n\n

El caso más sencillo es cuando todas las condiciones se unen con AND. Laravel permite pasar un array simple a where():

\n\n
<?php\n\n// Queremos encontrar usuarios activos de México, creados en 2024\n$usuarios = User::where([\n    ['status', '=', 'active'],\n    ['country', '=', 'Mexico'],\n    ['created_at', '>=', '2024-01-01'],\n])->get();\n\n// SQL: SELECT * FROM users WHERE status = 'active' AND country = 'Mexico' AND created_at >= '2024-01-01'
\n\n

¿Cuándo usarlo? Cuando tienes entre 2 y 5 condiciones simples con el operador = o >. El código queda legible, pero no es flexible.

\n\n

Desventaja: si necesitas mezclar AND y OR, el array no es suficiente.

\n\n

2. Cadena de métodos where() (para condiciones dinámicas)

\n\n

Este es el método más popular entre los desarrolladores. Simplemente llamas a where() varias veces seguidas:

\n\n
<?php\n\n$productos = Product::where('price', '>', 1000)\n    ->where('price', '<', 5000)\n    ->where('in_stock', true)\n    ->where('category_id', '!=', 5)\n    ->get();\n\n// SQL: ... WHERE price > 1000 AND price < 5000 AND in_stock = 1 AND category_id <> 5
\n\n

Truco: puedes combinarlo con otras condiciones:

\n\n
<?php\n\n// Condición "OR" dentro de la cadena\n$pedidos = Order::where('status', 'paid')\n    ->orWhere('status', 'shipped')\n    ->where('total', '>', 100)  // Atención: esta condición se aplica al orWhere anterior\n    ->get();\n\n// SQL: ... WHERE status = 'paid' OR (status = 'shipped' AND total > 100)
\n\n

⚠️ ¡Importante! En el último ejemplo, where total > 100 solo se aplica a status = 'shipped'. Si necesitas que ambos estados tengan total > 100, lee el siguiente punto.

\n\n

3. Agrupación de condiciones con closures (AND + OR combinados)

\n\n

Aquí llegamos a la herramienta más potente. Cuando necesitas crear un grupo de condiciones entre paréntesis, usa un closure dentro de where():

\n\n
<?php\n\n// Tarea: encontrar pedidos con estado "paid" o "shipped", \n// pero con total > 100 en ambos casos\n$pedidos = Order::where(function($query) {\n        $query->where('status', 'paid')\n              ->orWhere('status', 'shipped');\n    })\n    ->where('total', '>', 100)\n    ->get();\n\n// SQL: ... WHERE (status = 'paid' OR status = 'shipped') AND total > 100
\n\n

¡Ahora las condiciones están agrupadas correctamente! Puedes anidar closures tantas veces como necesites:

\n\n
<?php\n\n// Filtro complejo para análisis\n$datos = Sale::where('date', '>=', '2024-01-01')\n    ->where(function($q) {\n        $q->where('amount', '>', 10000)\n          ->orWhere('is_vip', true);\n    })\n    ->where(function($q) {\n        $q-&                

Blogs

Book Recommendations