laravel

Agrupar condiciones WHERE en SQL usando Laravel

En el post de hoy vamos a trabajar con Laravel, PHP y consultas SQL con WHERE. Como bien sabes, en MySQL o motores similares podemos agrupar condiciones usando paréntesis, estableciendo así un orden.

Por ejemplo, si queremos encerrar 2 condiciones y luego evaluarlas con un AND, haríamos algo así:

select * from `productos` where `id_establecimiento` = ? and (`descripcion` LIKE ? or `codigo_barras` LIKE ?) order by `descripcion` asc;

En este caso hacemos un and entre la primera comparación y el resultado de la segunda que está encerrada entre paréntesis para evaluar un or.

Esto es importante porque (para este ejemplo) si no se usaran paréntesis se podrían ver los productos de todos los establecimientos si es que el código de barras coincide.

Entonces veamos cómo agrupar y evaluar condiciones booleanas de la base de datos entre paréntesis usando el Query Builder y ORM de Laravel.

Funcionamiento de where y orWhere

Entonces veamos un ejemplo con un builder. Para agregar un WHERE hacemos lo siguiente:

<?php
$builder = Producto::orderBy("descripcion")->where("id_establecimiento", "=", Auth::user()->establecimiento->id);

En este caso usamos el método where del modelo de Laravel. La primera vez se agregará como un where normal sin operadores, pues es la única condición.

Si seguimos agregando más condiciones where entonces se colocará un and automáticamente.

Por otro lado, si queremos agregar un where pero que sea con OR, invocamos al método orWhere.

Laravel: agrupar condiciones WHERE de SQL

Podemos encerrar las condiciones entre paréntesis. Para ello podemos usar where o también orWhere, pero le pasamos una función como primer argumento.

Esa función recibirá un argumento en el cual podremos seguir usando los métodos del builder, pero todo lo que hagamos dentro de ella va a quedar entre paréntesis. Por ejemplo:

<?php
if ($busqueda) {
    $builder->where(function ($query) use ($busqueda) {
        $query->where("descripcion", "LIKE", "%$busqueda%")->orWhere("codigo_barras", "LIKE", "%$busqueda%");
    });
}

En este caso invoco a where con una función, y dentro de ella hago un where pero además un orWhere. Esas 2 condiciones se van a quedar encerradas entre paréntesis y evaluarse con las condiciones externas si es que existen.

Diferencia

Para depurar voy a devolver la consulta SQL generada por Laravel, así podrás ver la diferencia clara para agrupar las condiciones WHERE.

Veamos un primer ejemplo sin paréntesis. El builder queda así:

<?php
$builder = Producto::orderBy("descripcion")->where("id_establecimiento", "=", Auth::user()->establecimiento->id);
if ($busqueda) {
    $builder->where("descripcion", "LIKE", "%$busqueda%")->orWhere("codigo_barras", "LIKE", "%$busqueda%");
}

Generando la siguiente consulta que tiene un error de lógica ya que las últimas 2 condiciones deberían agruparse:

select * from `productos` where `id_establecimiento` = ? and `descripcion` LIKE ? or `codigo_barras` LIKE ? order by `descripcion` asc

Y ahora veamos cómo queda si agrupamos las condiciones. El código queda así:

<?php
$builder = Producto::orderBy("descripcion")->where("id_establecimiento", "=", Auth::user()->establecimiento->id);
if ($busqueda) {
    $builder->where(function ($query) use ($busqueda) {
        $query->where("descripcion", "LIKE", "%$busqueda%")->orWhere("codigo_barras", "LIKE", "%$busqueda%");
    });
}

Con la siguiente salida en la consulta, demostrando que las condiciones dentro de la función quedan entre paréntesis y se evalúan primero.

select * from `productos` where `id_establecimiento` = ? and (`descripcion` LIKE ? or `codigo_barras` LIKE ?) order by `descripcion` asc

Con todo lo que te mostré no quiero decir que sea malo no agrupar consultas o cosas similares, solo te enseñé cómo encerrar condiciones entre paréntesis si usas Laravel para interactuar con la base de datos SQL.

Para terminar te dejo con más tutoriales de Laravel en mi blog.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

6 días hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

6 días hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

6 días hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

6 días hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

6 días hace

Solución: Apache – Server unable to read htaccess file

Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…

7 días hace

Esta web usa cookies.