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?

veksen
quelle
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 ...)
Jarek Tkaczyk
quelle
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();
Luis Dalmolin
quelle
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();
Juljan
quelle
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')
Alexkle
quelle
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)
srmilon
quelle
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();
Majbah Habib
quelle
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

Alex Quintero
quelle
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();
DsRaj
quelle
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();
Adamk
quelle
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();
Lim Kean Phang
quelle
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

Aaron Cicali
quelle
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');
Cristhian Carreño
quelle
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();

Rahul Tathod
quelle
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();
Abhijeet Navgire
quelle
1
DB::table('users')
            ->where('name', '=', 'John')
            ->orWhere(function ($query) {
                $query->where('votes', '>', 100)
                      ->where('title', '<>', 'Admin');
            })
            ->get();
pardeep
quelle
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();
Dhruv Raval
quelle
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();
Sooraj Thekkepatt
quelle
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();

Craig GeRa
quelle
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'));
CodeToLife
quelle
-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'));
    }
}
Muhammad Arslan
quelle
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);
}
Yuri Lazo
quelle
Dadurch werden mehrere Abfragen ausgeführt.
Veksen