sql >> Base de Datos >  >> RDS >> Mysql

Laravel 5 usando la condición OR con BETWEEN

Hay un orWhereBetween disponible en Query Builder, pero no está documentado en la Query Builder Documentation . Sin embargo, puede encontrarlo en la Documentación de la API de Laravel .

Las explicaciones a continuación asumen que las variables tienen los siguientes valores:

$newStart = '1';
$newEnd = '10';

Desafortunadamente, usando orWhereBetween porque la segunda condición no es aplicable en su caso, porque tanto whereBetween y orWhereBetween comprobará si un valor de columna está entre dos valores de entrada. Esto está bien desde su primera condición, ya que comprueba si existing_start el valor de la columna está entre $newStart y $newEnd . Así que esto está bien:

->whereBetween('existing_start', [$newStart, $newEnd])

Como se compilará a:

WHERE `existing_start` BETWEEN '1' AND '10'

Sin embargo, su segunda condición quiere verificar si un valor de entrada de $newStart está entre dos valores de columna existing_start y existing_end , y no hay ningún método Query Builder que haga eso. Así que esto no funcionará:

->orWhereBetween($newStart, ['existing_start', 'existing_end'])

Porque se compilará para:

OR `1` BETWEEN 'existing_start' AND 'existing_end'

Observe los acentos graves ` alrededor de 1 , por eso MySQL intentará encontrar una columna llamada 1 y lanza un error.

Entonces, la mejor opción aquí es usar orWhereRaw con enlaces como este:

DB::table('tbl')
  ->whereBetween('existing_start', [$newStart, $newEnd])
  ->orWhereRaw('? BETWEEN existing_start AND existing_end', [$newStart])
  ->get();

El ? será reemplazado por el valor de $newStart que se citará correctamente y escapará para evitar la inyección de SQL.

O, por supuesto, siempre existe la opción de tener dos condiciones agrupadas que verifiquen los límites, lo que sería equivalente a su BETWEEN condición:

DB::table('tbl')
  ->whereBetween('existing_start', [$newStart, $newEnd])
  ->orWhere(function ($query) use ($newStart) {
      $query->where('existing_start', '<=', $newStart);
      $query->where('existing_end', '>=', $newStart);
  })->get();

Que compilará a:

SELECT * FROM `tbl`
WHERE
  `existing_start` BETWEEN '1' AND '10' OR
  (`existing_start` <= '1' AND `existing_end` >= '1')