584

I'm using the Laravel Eloquent query builder and I have a query where I want a WHERE clause on multiple conditions. It works, but it's not elegant.

Example:

$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();

Is there a better way to do this, or should I stick with this method?

miken32
  • 42,008
  • 16
  • 111
  • 154
veksen
  • 6,863
  • 5
  • 20
  • 33
  • 6
    There are many possibilities in terms of how this could be simplified, but that would require some more realistic code. Can you update the code to be a little more realistic? For example, there are times when multiple `->where(...)` calls can be replaced by a `->whereIn(...)` call, *et cetera*. – jonathanmarvens Oct 11 '13 at 19:08
  • 3
    The @Jarek Tkaczyk's solution should be the answer, I agree. But I'd prefer your code like builder script for comprehension and maintenance. – Tiefan Ju Nov 05 '18 at 16:17
  • Hope this link will be helpful to the future users in-depth multiple where condition example: https://www.scratchcode.io/laravel-multiple-where-conditions-with-example/ – Mayank Dudakiya Jan 07 '21 at 21:31
  • 1
    laravel requiring the first call to be static but the rest -> is really bad design. – ahnbizcad Jun 25 '21 at 18:04
  • @paresh-mangukiya please stop adding spurious tags to old questions. They are not helpful. – miken32 Dec 26 '21 at 22:29
  • For anyone seeing this after 2022, Laravel's query builder documentation has examples for [Advanced](https://laravel.com/docs/9.x/queries#advanced-where-clauses) and [Basic](https://laravel.com/docs/9.x/queries#basic-where-clauses) WHERE clauses. – BkiD Dec 21 '22 at 19:06

26 Answers26

885

In Laravel 5.3 (and still true as of 7.x) you can use more granular wheres passed as an array:

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

Personally I haven't found use-case for this over just multiple where calls, but fact is you can use it.

Since June 2014 you can pass an array to where

As long as you want all the wheres use and operator, you can group them this way:

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

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

Then:

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

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

The above will result in such query:

SELECT * FROM users
  WHERE (field = value AND another_field = another_value AND ...)
  OR (yet_another_field = yet_another_value AND ...)
shmuels
  • 1,039
  • 1
  • 9
  • 22
Jarek Tkaczyk
  • 78,987
  • 25
  • 159
  • 157
134

You can use subqueries in anonymous function like this:

 $results = User::where('this', '=', 1)
       ->where('that', '=', 1)
       ->where(
           function($query) {
             return $query
                    ->where('this_too', 'LIKE', '%fake%')
                    ->orWhere('that_too', '=', 1);
            })
            ->get();
Toby Allen
  • 10,997
  • 11
  • 73
  • 124
Juljan
  • 2,391
  • 1
  • 17
  • 20
  • Could you please link to the documentation for the likes of `orWhere`? I couldnt find it. – Carmageddon Apr 06 '23 at 19:24
  • Here you are: https://laravel.com/docs/10.x/queries "If you would like to use a "where" clause on your joins, you may use the where and orWhere methods provided by the JoinClause instance..." – Juljan Apr 11 '23 at 11:01
122

Query scopes may help you to let your code more readable.

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

Updating this answer with some example:

In your model, create scopes methods like this:

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

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

Then, you can call this scopes while building your query:

$users = User::active()->that()->get();
iainn
  • 16,826
  • 9
  • 33
  • 40
Luis Dalmolin
  • 3,416
  • 1
  • 18
  • 24
77

Conditions using Array:

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

Will produce query like below:

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

Conditions using Anonymous Function:

$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();

Will produce query like below:

SELECT * FROM TABLE WHERE column1 = value1 and (column2 = value2 or column3 = value3) and (column4 = value4 and column5 = value5)
w5m
  • 2,286
  • 3
  • 34
  • 46
56

In this case you could use something like this:

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

It should supply you with a query like:

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')
Barry
  • 3,303
  • 7
  • 23
  • 42
alexglue
  • 1,292
  • 12
  • 18
18
Model::where('column_1','=','value_1')
       ->where('column_2 ','=','value_2')
       ->get();

OR

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

OR

Model::where(['column_1' => 'value_1',
              'column_2' => 'value_2'])->get();
Toby Allen
  • 10,997
  • 11
  • 73
  • 124
DsRaj
  • 2,288
  • 1
  • 16
  • 26
15

Multiple where clauses

    $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);
    }

finally getting the result

    $result = $query->get();
Majbah Habib
  • 8,058
  • 3
  • 36
  • 38
10

The whereColumn method can be passed an array of multiple conditions. These conditions will be joined using the and operator.

Example:

$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();

For more information check this section of the documentation https://laravel.com/docs/5.4/queries#where-clauses

Alex Quintero
  • 1,160
  • 10
  • 21
7
$projects = DB::table('projects')->where([['title','like','%'.$input.'%'],
    ['status','<>','Pending'],
    ['status','<>','Not Available']])
->orwhere([['owner', 'like', '%'.$input.'%'],
    ['status','<>','Pending'],
    ['status','<>','Not Available']])->get();
Barry
  • 3,303
  • 7
  • 23
  • 42
Lim Kean Phang
  • 501
  • 4
  • 6
7

Multiple Where

  • You may also pass an array of conditions to the where function. Each element of the array should be an array containing the three arguments typically passed to the where method:
Model::where([
    ['status', '=', '1'],
    ['subscribed', '<>', '1'],
])->get();

Multiple Or Where Clauses

  • If you need to group an "or" condition within parentheses, you may pass a closure as the first argument to the orWhere method:
Model::where('votes', '>', 100)
        ->orWhere(function ($query) {
            $query->where('name', 'abcd')
                ->orWhere(function ($query) {
                    $query->where('name', 'cdef')
                        ->where('votes', '>', 50);
                });
        })
        ->get();

The example above will produce the following SQL:

select * from `users` where `votes` > 100 or (`name` = "abcd" or (`name` = "cdef" and `votes` > 50));

Mutipal where with whereNot and orWhereNot method

  • The whereNot and orWhereNot methods may be used to negate a given group of query constraints. For example, the following query excludes products that are on clearance or which have a price that is less than ten:
$products = Product::where([
        ['status', '=', '1'],
        ['is_feature', '1']
    ])
        ->whereNot(function ($query) {
            $query->where('clearance', true)
                ->orWhere('price', '<', 10);
        })
        ->get();
Nikunj Gadhiya
  • 138
  • 1
  • 7
5

Be sure to apply any other filters to sub queries, otherwise the or might gather all records.

$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();
Tunaki
  • 132,869
  • 46
  • 340
  • 423
adamk
  • 370
  • 4
  • 13
5

With Eloquent it is easy to create multiple where check:

First: (Use simple where)

$users = User::where('name', $request['name'])
    ->where('surname', $request['surname'])
    ->where('address', $request['address'])
    ...
    ->get();

Second: (Group your where inside an array)

$users = User::where([
    ['name', $request['name']],
    ['surname', $request['surname']],
    ['address', $request['address']],
    ...
])->get();

You can also use conditional (=, <>, etc.) inside where like this:

$users = User::where('name', '=', $request['name'])
    ->where('surname', '=', $request['surname'])
    ->where('address', '<>', $request['address'])
    ...
    ->get();
RCRalph
  • 355
  • 6
  • 17
Hedayatullah Sarwary
  • 2,664
  • 3
  • 24
  • 38
4

You may use in several ways,

$results = User::where([
    ['column_name1', '=', $value1],
    ['column_name2', '<', $value2],
    ['column_name3', '>', $value3]
])->get();

You can also use like this,

$results = User::orderBy('id','DESC');
$results = $results->where('column1','=', $value1);
$results = $results->where('column2','<',  $value2);
$results = $results->where('column3','>',  $value3);
$results = $results->get();
MaxiGui
  • 6,190
  • 4
  • 16
  • 33
3

As per my suggestion if you are doing filter or searching

then you should go with :

        $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
  • 1,535
  • 1
  • 8
  • 15
2

You can use eloquent in Laravel 5.3

All results

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

Partial results

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

You can use array in where clause as shown in below.

$result=DB::table('users')->where(array(
'column1' => value1,
'column2' => value2,
'column3' => value3))
->get();
Abhijeet Navgire
  • 683
  • 7
  • 20
2
DB::table('users')
            ->where('name', '=', 'John')
            ->orWhere(function ($query) {
                $query->where('votes', '>', 100)
                      ->where('title', '<>', 'Admin');
            })
            ->get();
pardeep
  • 359
  • 1
  • 5
  • 7
2

Use This

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

A sample of code.

Firstly :

$matchesLcl=[];

array gets filled here using desired count / loop of conditions, incremently :

 $matchesLcl['pos']= $request->pos;
$matchesLcl['operation']= $operation;
//+......+
$matchesLcl['somethingN']= $valueN;

and further with eloquents like this shrink expression :

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
  • 3,672
  • 2
  • 41
  • 29
0

Using pure Eloquent, implement it like so. This code returns all logged in users whose accounts are active. $users = \App\User::where('status', 'active')->where('logged_in', true)->get();

slimgera00
  • 66
  • 9
0

if your conditionals are like that (matching a single value), a simple more elegant way would be:

$results = User::where([
         'this' => value,
         'that' => value,
         'this_too' => value,
          ...
      ])
    ->get();

but if you need to OR the clauses then make sure for each orWhere() clause you repeat the must meet conditionals.

    $player = Player::where([
            'name' => $name,
            'team_id' => $team_id
        ])
        ->orWhere([
            ['nickname', $nickname],
            ['team_id', $team_id]
        ])
Ali Bakhshandeh
  • 433
  • 6
  • 10
0

We use this instruction to obtain users according to two conditions, type of user classification and user name.

Here we use two conditions for filtering as you type in addition to fetching user information from the profiles table to reduce the number of queries.

$users = $this->user->where([
                    ['name','LIKE','%'.$request->name.'%'],
                    ['trainers_id','=',$request->trainers_id]
                    ])->with('profiles')->paginate(10);
F. Müller
  • 3,969
  • 8
  • 38
  • 49
-1

You can do it as following, which is the shortest way.

    $results = User::where(['this'=>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])->get();
Toby Allen
  • 10,997
  • 11
  • 73
  • 124
Kaleem Shoukat
  • 811
  • 6
  • 14
-5
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'));
    }
}
-7

In Eloquent you can try this:

$results = User::where('this', '=', 1)
->orWhere('that', '=', 1)
->orWhere('this_too', '=', 1)
->orWhere('that_too', '=', 1)
->orWhere('this_as_well', '=', 1)
->orWhere('that_as_well', '=', 1)
->orWhere('this_one_too', '=', 1)
->orWhere('that_one_too', '=', 1)
->orWhere('this_one_as_well', '=', 1)
->orWhere('that_one_as_well', '=', 1)
->get();
Khawaja
  • 1
  • 1
-34
$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);
}
Abraham Uribe
  • 3,118
  • 7
  • 26
  • 34
Yuri Lazo
  • 1
  • 2