Wie erstelle ich eine Abfrage für mehrere Where-Klauseln mit Laravel Eloquent?


406

Ich verwende den Laravel Eloquent-Abfrage-Generator und habe eine Abfrage, in der ich eine WHEREKlausel für mehrere Bedingungen möchte . Es funktioniert, aber es ist nicht elegant.

Beispiel:

$results = User::where('this', '=', 1)
    ->where('that', '=', 1)
    ->where('this_too', '=', 1)
    ->where('that_too', '=', 1)
    ->where('this_as_well', '=', 1)
    ->where('that_as_well', '=', 1)
    ->where('this_one_too', '=', 1)
    ->where('that_one_too', '=', 1)
    ->where('this_one_as_well', '=', 1)
    ->where('that_one_as_well', '=', 1)
    ->get();

Gibt es einen besseren Weg, dies zu tun, oder sollte ich mich an diese Methode halten?


4
Es gibt viele Möglichkeiten, wie dies vereinfacht werden könnte, aber das würde einen realistischeren Code erfordern. Können Sie den Code aktualisieren, um etwas realistischer zu sein? Es gibt beispielsweise Zeiten, in denen mehrere ->where(...)Anrufe durch einen ->whereIn(...)Anruf usw. ersetzt werden können .
Jonathan Marvens

2
Die Lösung von @Jarek Tkaczyk sollte die Antwort sein, da stimme ich zu. Aber ich würde Ihren Code wie ein Builder-Skript zum Verständnis und zur Wartung bevorzugen.
Tiefan Ju

Antworten:


619

In Laravel 5.3 (und ab 7.x immer noch gültig) können Sie detailliertere Wherees verwenden, die als Array übergeben werden:

$query->where([
    ['column_1', '=', 'value_1'],
    ['column_2', '<>', 'value_2'],
    [COLUMN, OPERATOR, VALUE],
    ...
])

Persönlich habe ich keinen Anwendungsfall für nur mehrere whereAnrufe gefunden, aber Tatsache ist, dass Sie ihn verwenden können.

Seit Juni 2014 können Sie ein Array an übergeben where

Solange Sie alle wheresVerwendungsoperatoren möchten and, können Sie sie folgendermaßen gruppieren:

$matchThese = ['field' => 'value', 'another_field' => 'another_value', ...];

// if you need another group of wheres as an alternative:
$orThose = ['yet_another_field' => 'yet_another_value', ...];

Dann:

$results = User::where($matchThese)->get();

// with another group
$results = User::where($matchThese)
    ->orWhere($orThose)
    ->get();

Das Obige führt zu einer solchen Abfrage:

SELECT * FROM users
  WHERE (field = value AND another_field = another_value AND ...)
  OR (yet_another_field = yet_another_value AND ...)

8
Wie legen Sie den Operator fest?
Styphon

9
@Styphon Das tust du nicht. Derzeit funktioniert es nur mit =.
Jarek Tkaczyk

5
@Styphon und was ist, wenn ich machen möchte : WHERE (a IS NOT NULL AND b=1) OR (a IS NULL AND b=2);?
Alexglue

9
Sie können auch eine Reihe von Bedingungen wie diese übergeben:$users = DB::table('users')->where([ ['status', '=', '1'], ['subscribed', '<>', '1'], ])->get();
Nullen und Einsen

3
@jarek: Wie füge ich das whereNotInentsprechend deiner Antwort zu anderen whereCluases hinzu?
Kalanka

93

Abfragebereiche können Ihnen dabei helfen, Ihren Code besser lesbar zu machen.

http://laravel.com/docs/eloquent#query-scopes

Aktualisieren Sie diese Antwort mit einem Beispiel:

Erstellen Sie in Ihrem Modell folgende Bereichsmethoden:

public function scopeActive($query)
{
    return $query->where('active', '=', 1);
}

public function scopeThat($query)
{
    return $query->where('that', '=', 1);
}

Anschließend können Sie diese Bereiche beim Erstellen Ihrer Abfrage aufrufen:

$users = User::active()->that()->get();

Was ist die beste Vorgehensweise für eine Bedingung wie diese? Abfrage-> Wo ('start_date'> $ startDate) ist es immer noch in Ordnung, Bereiche zu verwenden?
Buwaneka Kalansuriya

72

Sie können Unterabfragen in anonymen Funktionen wie folgt verwenden:

 $results = User::where('this', '=', 1)
            ->where('that', '=', 1)
            ->where(function($query) {
                /** @var $query Illuminate\Database\Query\Builder  */
                return $query->where('this_too', 'LIKE', '%fake%')
                    ->orWhere('that_too', '=', 1);
            })
            ->get();

43

In diesem Fall könnten Sie Folgendes verwenden:

User::where('this', '=', 1)
    ->whereNotNull('created_at')
    ->whereNotNull('updated_at')
    ->where(function($query){
        return $query
        ->whereNull('alias')
        ->orWhere('alias', '=', 'admin');
    });

Es sollte Ihnen eine Abfrage liefern wie:

SELECT * FROM `user` 
WHERE `user`.`this` = 1 
    AND `user`.`created_at` IS NOT NULL 
    AND `user`.`updated_at` IS NOT NULL 
    AND (`alias` IS NULL OR `alias` = 'admin')

36

Bedingungen mit Array:

$users = User::where([
       'column1' => value1,
       'column2' => value2,
       'column3' => value3
])->get();

Erzeugt eine Abfrage wie unten:

SELECT * FROM TABLE WHERE column1=value1 and column2=value2 and column3=value3

Bedingungen mit anonymer Funktion:

$users = User::where('column1', '=', value1)
               ->where(function($query) use ($variable1,$variable2){
                    $query->where('column2','=',$variable1)
                   ->orWhere('column3','=',$variable2);
               })
              ->where(function($query2) use ($variable1,$variable2){
                    $query2->where('column4','=',$variable1)
                   ->where('column5','=',$variable2);
              })->get();

Erzeugt eine Abfrage wie unten:

SELECT * FROM TABLE WHERE column1=value1 and (column2=value2 or column3=value3) and (column4=value4 and column5=value5)

12

Mehrere where-Klauseln

    $query=DB::table('users')
        ->whereRaw("users.id BETWEEN 1003 AND 1004")
        ->whereNotIn('users.id', [1005,1006,1007])
        ->whereIn('users.id',  [1008,1009,1010]);
    $query->where(function($query2) use ($value)
    {
        $query2->where('user_type', 2)
            ->orWhere('value', $value);
    });

   if ($user == 'admin'){
        $query->where('users.user_name', $user);
    }

endlich das Ergebnis bekommen

    $result = $query->get();

9

Der whereColumnMethode kann ein Array mit mehreren Bedingungen übergeben werden. Diese Bedingungen werden mit dem andOperator verbunden.

Beispiel:

$users = DB::table('users')
            ->whereColumn([
                ['first_name', '=', 'last_name'],
                ['updated_at', '>', 'created_at']
            ])->get();

$users = User::whereColumn([
                ['first_name', '=', 'last_name'],
                ['updated_at', '>', 'created_at']
            ])->get();

Weitere Informationen finden Sie in diesem Abschnitt der Dokumentation unter https://laravel.com/docs/5.4/queries#where-clauses


8
Model::where('column_1','=','value_1')->where('column_2 ','=','value_2')->get();

ODER

// If you are looking for equal value then no need to add =
Model::where('column_1','value_1')->where('column_2','value_2')->get();

ODER

Model::where(['column_1' => 'value_1','column_2' => 'value_2'])->get();

5

Stellen Sie sicher, dass Sie andere Filter auf Unterabfragen anwenden, da sonst alle Datensätze erfasst werden.

$query = Activity::whereNotNull('id');
$count = 0;
foreach ($this->Reporter()->get() as $service) {
        $condition = ($count == 0) ? "where" : "orWhere";
        $query->$condition(function ($query) use ($service) {
            $query->where('branch_id', '=', $service->branch_id)
                  ->where('activity_type_id', '=', $service->activity_type_id)
                  ->whereBetween('activity_date_time', [$this->start_date, $this->end_date]);
        });
    $count++;
}
return $query->get();

Vielen Dank, dass Sie den 'use ($ service)' hinzugefügt haben. Juljans Antwort war fast das, was ich brauchte. Ihr Kommentar hat mir geholfen, meine Suchzeichenfolge an die Abfrage zu übergeben.
Elliot Robert

5
$projects = DB::table('projects')->where([['title','like','%'.$input.'%'],
    ['status','<>','Pending'],
    ['status','<>','Not Available']])
->orwhere([['owner', 'like', '%'.$input.'%'],
    ['status','<>','Pending'],
    ['status','<>','Not Available']])->get();

3

Ohne ein reales Beispiel ist es schwierig, eine Empfehlung abzugeben. Ich musste jedoch nie so viele WHERE-Klauseln in einer Abfrage verwenden, was möglicherweise auf ein Problem mit der Struktur Ihrer Daten hinweist.

Es kann hilfreich sein, sich mit der Datennormalisierung vertraut zu machen: http://en.wikipedia.org/wiki/Third_normal_form


3

Sie können eloquent in Laravel 5.3 verwenden

Alle Ergebnisse

UserModel::where('id_user', $id_user)
                ->where('estado', 1)
                ->get();

Teilergebnisse

UserModel::where('id_user', $id_user)
                    ->where('estado', 1)
                    ->pluck('id_rol');

3
Wie unterscheidet sich das von der Frage?
Veksen

2

Verwenden Sie whereInBedingung und übergeben Sie das Array

$array = [1008,1009,1010];

User::whereIn('users.id', $array)->get();


1

Sie können das Array in der where-Klausel verwenden, wie unten gezeigt.

$result=DB::table('users')->where(array(
'column1' => value1,
'column2' => value2,
'column3' => value3))
->get();

1
DB::table('users')
            ->where('name', '=', 'John')
            ->orWhere(function ($query) {
                $query->where('votes', '>', 100)
                      ->where('title', '<>', 'Admin');
            })
            ->get();

1

Gemäß meinem Vorschlag, wenn Sie filtern oder suchen

dann solltest du gehen mit:

        $results = User::query();
        $results->when($request->that, function ($q) use ($request) {
            $q->where('that', $request->that);
        });
        $results->when($request->this, function ($q) use ($request) {
            $q->where('this', $request->that);
        });
        $results->when($request->this_too, function ($q) use ($request) {
            $q->where('this_too', $request->that);
        });
        $results->get();

Findet die Suche auf der PHP- oder SQL-Seite statt?
Herr Mohamed

SQL-Seite. SQL-Abfrage als Anforderungsparameter ausführen. Ex. wenn requrst diesen param hat. Dann wo this = '' wo Bedingung zur Abfrage hinzugefügt.
Dhruv Raval

1

Benutze das

$users = DB::table('users')
                    ->where('votes', '>', 100)
                    ->orWhere('name', 'John')
                    ->get();

0

Implementieren Sie es mit reinem Eloquent wie folgt. Dieser Code gibt alle angemeldeten Benutzer zurück, deren Konten aktiv sind. $users = \App\User::where('status', 'active')->where('logged_in', true)->get();


0

Ein Beispiel für Code.

Zuerst :

$matchesLcl=[];

Das Array wird hier mit der gewünschten Anzahl / Schleife von Bedingungen schrittweise gefüllt :

if (trim($request->pos) != '') $matchesLcl['pos']= $request->pos;

und hier:

if (trim($operation) !== '')$matchesLcl['operation']= $operation;

und weiter mit Beredsamkeiten wie:

if (!empty($matchesLcl))
    $setLcl= MyModel::select(['a', 'b', 'c', 'd'])
        ->where($matchesLcl)
        ->whereBetween('updated_at', array($newStartDate . ' 00:00:00', $newEndDate . ' 23:59:59'));
else 
    $setLcl= MyModel::select(['a', 'b', 'c', 'd'])
        ->whereBetween('updated_at', array($newStartDate . ' 00:00:00', $newEndDate . ' 23:59:59'));

-4
public function search()
{
    if (isset($_GET) && !empty($_GET))
    {
        $prepareQuery = '';
        foreach ($_GET as $key => $data)
        {
            if ($data)
            {
                $prepareQuery.=$key . ' = "' . $data . '" OR ';
            }
        }
        $query = substr($prepareQuery, 0, -3);
        if ($query)
            $model = Businesses::whereRaw($query)->get();
        else
            $model = Businesses::get();

        return view('pages.search', compact('model', 'model'));
    }
}

Dies ist sehr anfällig für SQL-Injection.
rrrhys

-21
$variable = array('this' => 1,
                    'that' => 1
                    'that' => 1,
                    'this_too' => 1,
                    'that_too' => 1,
                    'this_as_well' => 1,
                    'that_as_well' => 1,
                    'this_one_too' => 1,
                    'that_one_too' => 1,
                    'this_one_as_well' => 1,
                    'that_one_as_well' => 1);

foreach ($variable as $key => $value) {
    User::where($key, '=', $value);
}

Dadurch werden mehrere Abfragen ausgeführt.
Veksen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.