Eloquent grouped orWhere - php

Currently have an Eloquent statement:
$contacts = Contacts::where('lname','LIKE',$searchquery.'%')
->orWhere('fname','LIKE',$searchquery.'%')
->orWhere('phone','LIKE','%'.$searchquery)
->where('active','=',1)->get();
It is treating it as
select
*
from
contacts
where
lname like $searchquery+'%'
or lname like $searchquery+'%'
or lname like $searchquery+'%'
and active = 1
what I am needing is
select
*
from
contacts
where
(lname like $searchquery+'%'
or lname like $searchquery+'%'
or lname like $searchquery+'%')
and active = 1
How do I go about grouping in Eloquent? I have found a couple examples such as:
DB::table('users')
->where('name', '=', 'John')
->orWhere(function ($query) {
$query->where('votes', '>', 100)
->where('title', '<>', 'Admin');
})
->get();
But I am only used to Eloquent, not Laravels DB Query builder. I tried adapting the Eloquent form to this
$contacts = Contacts::->where('active', '=', '1')
->where(function ($query) {
$query->orWhere('lname', 'LIKE', $searchquery.'%')
->orWhere('lname', 'LIKE', $searchquery.'%')
->orWhere('phone', 'LIKE', '%'.$searchquery);
})
->get();
No success as it does not recognize the $searchquery inside the function.
What am I missing?

So, this is what you have to do:
DB::table('users')->where(function($query) use ($searchQuery){
$query->where('lname', 'LIKE', $searchQuery . '%')
->orWhere('fname', 'LIKE', $searchQuery . '%')
->orWhere('phone','LIKE', '%' . $searchquery);
})
->get();
Note that I've put use ($searchQuery) so it can be used inside the closure

When you use orWhere with multiple where clauses, you need to be careful!
Where clauses after orWhere doesn't effected to sibling where clauses before orWhere clauses such as where, whereHas, whereDoesntHave, orWhereHas
also you have to pass $searchquery variable inside to function in where clause using use ($searchquery)
Contacts::->where(function ($query) use ($searchquery) {
$query->orWhere('lname', 'LIKE', $searchquery.'%')
->orWhere('lname', 'LIKE', $searchquery.'%')
->orWhere('phone', 'LIKE', '%'.$searchquery);
})
->where('active', '=', '1')
->get();

Related

Laravel 8 Livewire search filter not working with first where clause

I want to have a table which shows all the data per company that has a filter search input, the problem is when I put the first argument where('company_id', Auth::user()->company_id) it bugs out and doesn't make the filter search work.
$groups = Group::where('company_id', Auth::user()->company_id)
->orWhere('code', 'like', $filter)
->orWhere('name', 'like', $filter)
->orWhere('description', 'like', $filter)
->orWhereRaw("(CASE WHEN active = 1 THEN 'Active' ELSE 'Inactive' END) LIKE '%$filter%'")
->orderBy($this->column, $this->order)
->paginate($this->size);
This is my query for the table.
I suppose you want company_id filter to apply to all query and combine other orWhere conditions. The other orWhere should be grouped in query like this:
$groups = Group::where('company_id', Auth::user()->company_id)
->where(function ($query) use ($filter) {
return $query->where('code', 'like', $filter)
->orWhere('name', 'like', $filter)
->orWhere('description', 'like', $filter)
->orWhereRaw("(CASE WHEN active = 1 THEN 'Active' ELSE 'Inactive' END) LIKE '%$filter%'");
})
->orderBy($this->column, $this->order)
->paginate($this->size);
I have solved the query, by adding another where statement with the other orWhere the syntax is below.
For some reason the syntax above worked for Vue but when I migrated Vue to Livewire
$groups = Group::where('company_id', Auth::user()->company_id)
->where('code', 'like', $filter)
->orWhere('name', 'like', $filter)
->orWhere('description', 'like', $filter)
->orWhereRaw("(CASE WHEN active = 1 THEN 'Active' ELSE 'Inactive' END) LIKE '%$filter%'")
->orderBy($this->column, $this->order)
->paginate($this->size);

Laravel eloquent: How to filter with where() and whereHas()

I am trying to filter my users based on categories in which they have posted something and also the users directly by search string:
$users = User::when($search, function ($query) use ($request) {
$query->where('name', 'like', '%' . $request['search'] . '%')
->orWhere('email', 'like', '%' . $request['search'] . '%');
return $query;
})
->when($categories, function ($query) use ($request) {
return $query->whereHas('posts.category', function ($query) use ($request) {
$query->whereIn('name', $request['categories']);
});
})
->select('id', 'name', 'email')
->paginate(10);
When I filter for categories only (without $search) it is working as expected but as soon as I type a search string the result is filtered by the search string $request['search'] but ignores the category filtering completely.
So for example:
The user named "Jon" has a post in category "Lifestyle".
Another user named "Jonn" has a post in category "Sports".
Now if I filter for category only "Sports" I get the correct result -> "Jonn".
But if I filter additionally with the search string "Jon" the result is -> "Jon" and "Jonn" which is not the expected result because it should filter for "Sports" and name "%Jon%" so again the result should be only "Jonn".
I don't know how I can achieve that filter combination of where() and whereHas().
Your issue is nesting of the constraints. Translated to SQL, your query looks like this:
SELECT id, name, email
FROM users
WHERE name like '%foo%'
OR address like '%foo%'
OR email like '%foo%'
AND EXISTS (
SELECT *
FROM categories c
INNER JOIN posts p ON p.category_id = c.id
WHERE c.name IN ('bar', 'baz')
)
Note: pagination omitted
As you can see, it isn't quite clear what the WHERE statements are supposed to do. But that can be fixed rather easily by wrapping all of the search constraints in an extra where():
$users = User::when($search, function ($query) use ($request) {
$query->where(function $query) use ($request) {
$query->where('name', 'like', '%' . $request['search'] . '%')
->orWhere('address', 'like', '%' . $request['search'] . '%')
->orWhere('email', 'like', '%' . $request['search'] . '%');
});
})
->when($categories, function ($query) use ($request) {
$query->whereHas('posts.category', function ($query) use ($request) {
$query->whereIn('name', $request['categories']);
});
})
->select('id', 'name', 'email')
->paginate(10);
This way your query will look like this:
SELECT id, name, email
FROM users
WHERE
(
name like '%foo%'
OR address like '%foo%'
OR email like '%foo%'
)
AND EXISTS (
SELECT *
FROM categories c
INNER JOIN posts p ON p.category_id = c.id
WHERE c.name IN ('bar', 'baz')
)
A small note on the side: You don't have to return the $query from the callbacks.
You can try like this:
$users = User::where(function ($query) {
$query->when($search, function ($query) use ($request) {
$query->where('name', 'like', '%' . $request['search'] . '%')
->orWhere('address', 'like', '%' . $request['search'] . '%')
->orWhere('email', 'like', '%' . $request['search'] . '%');
})
$query->when($categories, function ($query) use ($request) {
$query->whereHas('posts.category', function ($query) use ($request) {
$query->whereIn('name', $request['categories']);
});
})
})
->select('id', 'name', 'email')
->paginate(10);
I think you don't need your return. But you can achieve what do you want if you put your when statements in one where function like this.
I didn't test this solution so if you have errors provide it in comment.
Good luck!

MySQL query to Laravel 5.5

SELECT * FROM table WHERE age = 10 AND (first_name like %name% OR last_name like %name%);
How do you do this in Laravel 5.5?
Using query builder:
$results = DB::table('table')
->where('age', 10)
->where(function ($query) {
$query
->where('first_name', 'like', '%name%')
->orWhere('last_name', 'like', '%name%');
})
->get();
Check the official documentation (5.5) for Query Builder
You can do something like this to query
$data= DB::table('table')
->whereRaw('age'= ? AND (first_name like ? OR last_name like ?)', [10,'%'.name.'%','%'.name.'%' ])
->get();'
Official documentation to select https://laravel.com/docs/5.6/queries#selects
I don't know how many field do you use in your view.. but if you have firstname field and lastname field, then your code should be like this:
$results = DB::table('table')
->where('age', 10)
->where(function ($query) use ($request) {
$query
->where('first_name', 'LIKE', '%' . $request->first_name .'%')
->orWhere('last_name', 'LIKE', '%' . $request->last_name .'%');
})
->get();

laravel DB:table for multi where AND Or condition for multiple slected field

My query like :
$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();
Solution for the multi where condition in laravel ,because its not working currently
->where('twd.status','=','0')->where(function($q) use($data){
$q->where('A','like', '%' .$data. '%')
->orWhere('B','like', '%' .$data. '%');
->orWhere('C','like', '%' .$search_param. '%');
})
You can do it like that .
Concat all column that you want to search
->where(DB::raw("concat(A,' ',B)"), 'like', "%".$data."%");

Left join not working properly

I'm trying to search all the users registered for a particular course using the following query using the laravel.
$users = DB::table('users')
->leftJoin('registrationrequests', 'users.id', '=', 'registrationrequests.user_id')
->where('firstname', 'LIKE', "%$search%")
->orWhere('lastname', 'LIKE', "%$search%")
->orWhere('username', 'LIKE', "%$search%")
->where('registrationrequests.course_id', $course_id)
->where('registrationrequests.registered', 1)
->get();
In the table registrationrequests, I have columns for course_id, user_id and registered (binary value). course_id and user_id are foreign keys for respective tables.
I'm getting an array of output. But it's not checking the condition where('registrationrequests.course_id', $course_id)
What might be the reason?
Using http://laravel.com/docs/4.2/queries#advanced-wheres and https://stackoverflow.com/a/18660266/689579 your query would look something like -
$users = DB::table('users')
->leftJoin('registrationrequests', 'users.id', '=', 'registrationrequests.user_id')
->where('registrationrequests.course_id', $course_id)
->where('registrationrequests.registered', 1)
->where(function($users) use($search){
$users->where('firstname', 'LIKE', "%$search%")
->orWhere('lastname', 'LIKE', "%$search%")
->orWhere('username', 'LIKE', "%$search%")
})
->get();

Categories