Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Laravel 5 mit ODER-Bedingung mit BETWEEN

Es gibt ein orWhereBetween -Methode, die vom Abfragegenerator verfügbar ist, aber in der Dokumentation zum Abfragegenerator . Sie finden es jedoch in der Laravel API Documentation .

Die nachfolgenden Erläuterungen gehen davon aus, dass die Variablen folgende Werte haben:

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

Leider mit orWhereBetween denn die zweite Bedingung trifft in Ihrem Fall nicht zu, da beide whereBetween und orWhereBetween überprüft, ob ein Spaltenwert zwischen zwei Eingabewerten liegt. Dies ist ab Ihrer ersten Bedingung in Ordnung, da es prüft, ob der existing_start Spaltenwert liegt zwischen $newStart und $newEnd . Das ist also in Ordnung:

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

Wie es kompiliert wird zu:

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

Ihre zweite Bedingung möchte jedoch prüfen, ob ein Eingabewert von $newStart vorliegt liegt zwischen zwei Spaltenwerten existing_start und existing_end , und es gibt keine Query Builder-Methode, die das tut. Das wird also nicht funktionieren:

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

Weil es kompiliert wird zu:

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

Beachten Sie die Backticks ` um 1 , deshalb wird MySQL versuchen, eine Spalte mit dem Namen 1 zu finden und einen Fehler ausgeben.

Die beste Option ist hier also die Verwendung von orWhereRaw mit Bindungen wie dieser:

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

Der ? wird durch den Wert von $newStart ersetzt die korrekt in Anführungszeichen gesetzt und maskiert werden, um eine SQL-Einschleusung zu vermeiden.

Oder natürlich gibt es immer die Möglichkeit, zwei gruppierte Bedingungen zu haben, die die Grenzen prüfen, was Ihrem BETWEEN entsprechen würde Bedingung:

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

Was kompiliert wird zu:

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