Combing multiple orWhere() in Laravel 9 Eloquent - php

Is it possible to combine multiple orWhere() inside one where()?
E.g. The following:
$query->where(function($query){
$query->where('text1', '=', $_GET['lorem'])
->orWhere('text2', '=', $_GET['lorem'])
->orWhere('text3', '=', $_GET['lorem'])
->orWhere('text4', '=', $_GET['lorem']);
});
Would look something like this:
$query->where(function($query){
$query->where(['text1' || 'text2' || 'text3' || 'text4'], '=', $_GET['lorem']);
});
P.S. In the above hypothetical example, the [ ] aren't really referring to an array but I'm just using the brackets to group text1/2/3/4.

$query->where(function($query){
$columns = ['text1', 'text2', 'text3'];
foreach($columns as $column){
$query->OrWhere($column, '=', $_GET['lorem']);}});
This might work

Try this...
$columns = ['text1', 'text2', 'text3'];
$query->where(function ($query) use ($columns) {
foreach ($columns as $key => $column) {
if ($key == 0) $query->where($column, '=', $_GET['lorem']);
else $query->OrWhere($column, '=', $_GET['lorem']);
}
});

It looks like the documentation for this actually does allow you to pass an array of equal statements in a key-value arrangement.
$columns = [
'text1'=>$value,
'text2'=>$value,
'text3'=>$value
];
$query->where($columns);
You can see this works from the laravel docs in 9.X
https://github.com/laravel/framework/blob/29430b413b29fb60073ad26682a572df2ab5f5b2/src/Illuminate/Database/Query/Builder.php#L703
This shows the builder where clause. Following this, are the lines 708-710 which take the array and make it into the looped where statement that has been a solution for you up until now.
Please note that this method seems to only work with '=' as far as I can see.
TLDR:
Put key-value array into first param of where method.

Related

Invalid argument supplied for foreach() laravel using whereIn (laravel 5.3)

I am getting ids using jquery in my controller its as
if(!empty($request->input('ids'))) {
$ids = $request->input('ids');
}else{
$ids = null;
}
I try dd($ids)
Output is as in my console
array:3 [
0 => "1"
1 => "2"
2 => "on"
]
When i pass ids to my query as
Query
$student_ids = DB::table('students')
->orderBy('name', 'asc')
->where('group_id', '<>', 0)
->whereIn('students.id','=', $ids)
->pluck('id');
Its not working
Error is : Invalid argument supplied for foreach
Please help where I am wrong. Thanks
You should change this:
->whereIn('students.id','=', $ids)
To this:
->whereIn('students.id', $ids)
Because the second parameter should be iterable of IDs, but you're passing a string =. Also, make sure, you're passing an array or collection of IDs.
Change:
where('students.id', '=', $ids)
To:
whereIn('students.id', $ids);
Like others have mentioned update the whereIn parameter. Also simplify your request input like so.
$ids = $request->input('ids', []);
$student_ids = DB::table('students')
->orderBy('name', 'asc')
->where('group_id', '<>', 0)
->whereIn('students.id', $ids)
->pluck('id');

Can I do Model->where('id', ARRAY) multiple where conditions?

The title says it all.
I get that I can do this :
DB::table('items')->where('something', 'value')->get()
But what I want to check the where condition for multiple values like so:
DB::table('items')->where('something', 'array_of_value')->get()
Is there an easy way of doing this?
There's whereIn():
$items = DB::table('items')->whereIn('id', [1, 2, 3])->get();
You could use one of the below solutions:
$items = Item::whereIn('id', [1,2,..])->get();
or:
$items = DB::table('items')->whereIn('id',[1,2,..])->get();
If you need by several params:
$ids = [1,2,3,4];
$not_ids = [5,6,7,8];
DB::table('table')->whereIn('id', $ids)
->whereNotIn('id', $not_ids)
->where('status', 1)
->get();
You can use whereIn which accepts an array as second paramter.
DB:table('table')
->whereIn('column', [value, value, value])
->get()
You can chain where multiple times.
DB:table('table')->where('column', 'operator', 'value')
->where('column', 'operator', 'value')
->where('column', 'operator', 'value')
->get();
This will use AND operator. if you need OR you can use orWhere method.
For advanced where statements
DB::table('table')
->where('column', 'operator', 'value')
->orWhere(function($query)
{
$query->where('column', 'operator', 'value')
->where('column', 'operator', 'value');
})
->get();
If you are searching by ID you can also use:
$items = Item::find(array_of_ids);
It's work for me
fetch just id then search in array
$shops = Shop::Where('user_id', Auth::id())->get('id');
$categories = Category::whereIn('shop_id',$shops)->paginate(7);
$whereData = [['name', 'test'], ['id', '<>', '5']];
$users = DB::table('users')->where($whereData)->get();
WHERE AND SELECT Condition In Array Format Laravel
use DB;
$conditions = array(
array('email', '=', 'user#gmail.com')
);
$selected = array('id','name','email','mobile','created');
$result = DB::table('users')->select($selected)->where($conditions)->get();

Laravel Eloquent orWhere Query

Can someone show me how to write this query in Eloquent?
SELECT * FROM `projects` WHERE `id`='17' OR `id`='19'
I am thinking
Project::where('id','=','17')
->orWhere('id','=','19')
->get();
Also my variables (17 and 19) in this case are coming from a multi select box, so basically in an array. Any clues on how to cycle through that and add these where/orWhere clauses dynamically?
Thanks.
You could do in three ways. Assume you've an array in the form
['myselect' => [11, 15, 17, 19], 'otherfield' => 'test', '_token' => 'jahduwlsbw91ihp'] which could be a dump of \Input::all();
Project::where(function ($query) {
foreach(\Input::get('myselect') as $select) {
$query->orWhere('id', '=', $select);
}
})->get();
Project::whereIn('id', \Input::get('myselect'))->get();
$sql = \DB::table('projects');
foreach (\Input::get('myselect') as $select) {
$sql->orWhere('id', '=', $select);
}
$result = $sql->get();
The best approach for this case is using Laravel's equivalent for SQL's IN().
Project::whereIn('id', [17, 19])->get();
Will be the same as:
SELECT * FROM projects WHERE id IN (17, 19)
This approach is nicer and also more efficient - according to the Mysql Manual, if all values are constants, IN sorts the list and then uses a binary search.
In laravel 5 you could do it this way.
$projects = Projects::query();
foreach ($selects as $select) {
$projects->orWhere('id', '=', $select);
}
$result = $projects->get();
This is very useful specially if you have custom methods on your Projects model and you need to query from variable. You cannot pass $selects inside the orWhere method.
public function getSearchProducts($searchInput)
{
$products = Cache::rememberForever('getSearchProductsWithDiscountCalculationproducts', function () {
return DB::table('products_view')->get();
});
$searchProducts = $products->filter(function ($item) use($searchInput) {
return preg_match('/'.$searchInput.'/i', $item->productName) || preg_match('/'.$searchInput.'/i', $item->searchTags) ;
});
$response = ["status" => "Success", "data" => $searchProducts ];
return response(json_encode($response), 200, ["Content-Type" => "application/json"]);
}
use filter functionality for any customize situations.

Eloquent select rows with empty string or null value

I have something like $user->albums()->where('col', NULL), it works fine then I tried to extend it to empty strings with $user->albums()->where('col', NULL)->or_where('col', '') and it's not working.
Also I saw on this post that I could use where_null('col') but it's not working and it's not documented. Any simple method to select where empty or NULL col
Try using orWhereNull for the second clause:
$users = DB::table('users')
->where('col', '=', '')
->orWhereNull('col')
->get();
Or if you have multiple conditions in the query, you have to wrap the two in a closure:
$users = DB::table('users')
->where(function(\Illuminate\Database\Eloquent\Builder $query) {
$query->where('col', '')->orWhereNull('col');
})
->where('col2','val2')
->get();
How about this:
$user->albums()->whereRaw("NOT col > ''")
This way you can check both conditions at the same time
Try this query:
$users = DB::table('users')
->whereRaw('col = "" OR col IS NULL')
->get();
I always encourage to create queries with the main Laravel functions that are most used.
That's why you must have 2 things in mind:
algorithm. key1 = value1 AND key2 = value2 OR key3 = value3. Be very carreful about precedence because in the way I exemplified there will be a main OR not an AND with OR inside
using where(), whereIn(), whereNull and closure instead of whereRaw(). whereRaw is using more memory than any others I mentioned.
So, to resume your answer:
OR condition
$users = DB::table('users')
->where('col', '=', '')
->orWhere('col','=','')
->whereNull('col')
->get();
AND and OR condition
$users = DB::table('users')
->where(function($query) { $query->where('col','=','')->orWhere('col','=','')->whereNull('col'); })
->where('col','=','')
->get();
The below solution is tested on LARAVEL 9. Solution is to add to the App\Providers\AppServiceProvider this piece of code:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
///...
Builder::macro('whereNullOrEmpty', function ($field) {
return $this->where(function ($query) use ($field) {
return $query->where($field, '=', null)->orWhere($field, '=', '');
});
});
Builder::macro('whereNotNullOrEmpty', function ($field) {
return $this->where(function ($query) use ($field) {
return $query->where($field, '<>', null)->where($field, '<>', '');
});
});
}
//...
}
and then call it like this:
if($nullOrEmpty){
$builder->whereNullOrEmpty('col');
}else{
$builder->whereNotNullOrEmpty('col');
}
You must call both commands:
where($field, '<>', null);
where($field, '<>', '');
because the MySql is handling empty strings and nulls different than a PHP
you also need to wrap those two commands with the closure to tell Eloquent to put generated code in parentheses and isolate MySql code:
(where col = null or where col = '')
Not sure, but this might work:
$user->albums()->where_in('col', array(NULL,''));

Combining AND/OR eloquent query in Laravel

How can I write following or similar kind of queries using Eloquent?
SELECT * FROM a_table WHERE (a LIKE %keyword% OR b LIKE %keyword%) AND c = 1 AND d = 5
I couldn't combine AND/OR in the way I wanted by chaining where & or_where functions.
You can nest where clauses : http://laravel.com/docs/database/fluent#nested-where
Model::where(function($query)
{
$query->where('a', 'like', 'keyword');
$query->or_where('b', 'like', 'keyword');
})
->where('c', '=', '1');
This should produce : SELECT * FROM models WHERE (a LIKE %keyword% OR b LIKE %keyword%) AND c = 1
For a more accurate answer to the example:
$val = '%keyword%';
A_Table_Model::where(function($query) use ($val)
{
$query->where('a', 'like', $val);
$query->or_where('b', 'like', $val);
})
->where('c', '=', 1)
->where('d', '=', 5)
->get();
Note: This is Laravel 3 syntax, use camelCase orWhere() for Laravel 4
In Laravel 5.1+ this will also do the job and looks cleaner:
Model::where(function($query) {
$query->where('a', 'like', 'keyword');
$query->or_where('b', 'like', 'keyword');
})->where('c', '=', '1')->get();
You can use DB::raw() in the first where() to put in the like/or statement.

Categories