Laravel join with "and" and "or" in the where clause - php

How can I write a Laravel 5 Eloquent query like this SQL?
where ( (table1.fname like %xxxxx% )
OR (table1.lname like %xxxxx%) )
AND table1.is_active != 0
I have already tried
->where('users.is_active', '!=', 2)
->where('users.name', 'like' , '%'. $search .'%')
->orWhere('users.lname', 'like' , '%'. $search .'%')
->orWhere('users.email', 'like' , '%'. $search .'%') ->get();

Take a look at the Advanced join Clauses in Laravel Documentation
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
joins
EDIT
I think i misunderstood the question. To do nested wheres you can do the following thing:
\DB::table('table1')->...->where(function($query) {
$query->where('table1.fname', 'like', '%xxxxx$')->orWhere('table1.lname', 'like', '%xxxx%);
})->where('table1.is_active', '!=', 0);

You can use Model for this:
TableModel::where('fname', 'like', '%xxxxx%')
->orWhere('lname', 'like', '%xxxxx%')
->where('is_active', '!=', 0)
->get();

$data = DB::table('table1')->where('fname', 'like', '%xxxxx%')
->orWhere('lname', 'like', '%xxxxx%')
->where('is_active', '!=', 0)
->get();
//add use DB; in your controller

To have grouped sub-clauses that should evaluate as a whole, you can pass where() a closure. Then you want a second where call for the check on the is_active column:
$value = '%xxxxx%';
$collection = Model::where(function ($models) use ($value) {
$models->where('fname', 'like', $value)
->orWhere('lname', 'like', $value);
})
->where('is_active', '!=', 0)
->get();

Related

Laravel eloquent returning wrong data

I have conditional data and it ignores that conditions while returning data:
Works fine
$orders = Order::where('user_id', $user->id)->with(['customer', 'laundry', 'driver', 'driver.user', 'progresses' => function($p){
$p->orderby('created_at', 'asc');
}, 'progresses.progress', 'services'])->get();
Return wrong data
$orders = Order::where('user_id', $user->id)->with(['customer', 'laundry', 'driver', 'driver.user', 'progresses' => function($p){
$p->orderby('created_at', 'asc');
}, 'progresses.progress', 'services'])
->where('id', 'like', '%'.$this->search.'%')
->orWhere('transport', 'like', '%'.$this->search.'%')
->orWhere('amount', 'like', '%'.$this->search.'%')
->orWhere('weight', 'like', '%'.$this->search.'%')
->orWhere('total', 'like', '%'.$this->search.'%')
->paginate(10);
Issue
The second query return all orders and ignores where('user_id', '=', $user->id).
Question
why it ignore where('user_id', '=', $user->id)
How to fix it?
You should group your search LIKE query here
Order::with(
[
'customer',
'laundry',
'driver',
'driver.user',
'progresses' => function($p) {
$p->orderby('created_at', 'asc');
},
'progresses.progress',
'services'
]
)->where('user_id', $user->id)
->where(function($q) {
$q->where('id', 'like', '%'.$this->search.'%')
->orWhere('transport', 'like', '%'.$this->search.'%')
->orWhere('amount', 'like', '%'.$this->search.'%')
->orWhere('weight', 'like', '%'.$this->search.'%')
->orWhere('total', 'like', '%'.$this->search.'%');
})->paginate(10);
So the query string is look like:
WHERE user_id = ?
AND
(id LIKE ? OR transport LIKE ? OR amount LIKE ? OR weight LIKE ? OR total LIKE ?)
It will ignore the where('user_id', '=', $user->id) because of orWhere on your search LIKE query

Is It possible not to use orWhere and use like where['col', 'val' OR 'col_2','val_2' ] in laravel? [duplicate]

I have the following code:
$results = \DB::table('pack')
->Join('users as u1', 'u1.id', '=', 'pack.userid')
->Join('skills as s1', 's1.packid', '=', 'pack.packid')
->where('u_status', '=', "0")
->where('pack.amount', '<', 100)
->where('pack.amount', '>', 10)
->where('pack_status', '=', "2")
->where('pack.title', 'LIKE', "%$text%")
->orWhere('pack.description', 'LIKE', "%$text%")
->orWhere('pack.skills', 'LIKE', "%$text%")
->orWhere('s1.name', 'LIKE', "%$text%")
->orderBy('packid', 'desc')
->orderBy('featured', 'desc')
->groupBy('packid')
->take(40)
->get();
return $results;
Everything is working except ->where('amount', '<', 100) and ->where('amount', '>', 10).
It does not exclude either of those, and shows amounts above and below the numbers I set. If I remove the orWhere() it works fine.
Am I using orWhere() and where() correctly?
The issue is that you've combined ORs and ANDs without grouping them properly. Think about the following conditions:
$bool1 = false && false || true; // =true
$bool2 = false && (false || true); // =false
So, to get this to work properly, you need to group your conditions properly. You can group conditions by passing a closure to the where() or orWhere() methods. I'm guessing you want to group the $text conditions together, so your code would look like:
$results = \DB::table('pack')
->join('users as u1', 'u1.id', '=', 'pack.userid')
->join('skills as s1', 's1.packid', '=', 'pack.packid')
->where('u_status', '=', "0")
->where('pack.amount', '<', 100)
->where('pack.amount', '>', 10)
->where('pack_status', '=', "2")
->where(function($query) use ($text) {
$query->where('pack.title', 'LIKE', "%$text%")
->orWhere('pack.description', 'LIKE', "%$text%")
->orWhere('pack.skills', 'LIKE', "%$text%")
->orWhere('s1.name', 'LIKE', "%$text%");
})
->orderBy('packid', 'desc')
->orderBy('featured', 'desc')
->groupBy('packid')
->take(40)
->get();
return $results;
If your database row matches any of the orWhere it will show the row. In your code you have
->orWhere('pack.description', 'LIKE', "%$text%")
->orWhere('pack.skills', 'LIKE', "%$text%")
->orWhere('s1.name', 'LIKE', "%$text%")
If you row matches any of them it will ignore other where or orWhere

Laravel where clause is not returning data after multiple orWhere clauses?

I am using laravel 6.10 version in that I am implementing search,
I have 3 tables
1) course_category
2) course_sub_category
3) course [course_id_category(foreign key),course_sub_category_id(foreign key)]
below is my code
$course = $request->searchItem;
if ($course=="") {
$Courses = DB::table('course')
->join('course_category', 'course.course_category_id', '=', 'course_category.id')
->select('course.*','course_category.title as category_title','course_category.thumb as category_thumb')
->orderBy('course.title','asc')
->paginate(15);
}
else{
$Courses = DB::table('course')
->join('course_category', 'course.course_category_id', '=', 'course_category.id')
->join('course_sub_category', 'course.course_sub_category_id', '=', 'course_sub_category.id')
->select('course.*','course_category.title as category_title','course_category.thumb as category_thumb')
->where('course.title', 'LIKE', '%'.$course.'%')
->orWhere('course_category.title', 'LIKE', '%'.$course.'%')
->orWhere('course_sub_category.title', 'LIKE', '%'.$course.'%')
->get();
}
when i am retunring the values i am gatting 0 arrays but when i am removing one orwhere from existing my query is working and its returnig we all values with match
means when i am using multiple orWhere in laravel my where is not working, please share the solution on same.
->orWhere doesnt work like typical SQL. You should use it like that:
$Courses = DB::table('course')
->join('course_category', 'course.course_category_id', '=', 'course_category.id')
->join('course_sub_category', 'course.course_sub_category_id', '=', 'course_sub_category.id')
->select('course.*','course_category.title as category_title','course_category.thumb as category_thumb')
->where(function($query) use ($course){
$query->where('course.title', 'LIKE', '%'.$course.'%')
$query->orWhere('course_category.title', 'LIKE', '%'.$course.'%')
$query->orWhere('course_sub_category.title', 'LIKE', '%'.$course.'%')
})
->get();

Filter query not working through Laravel query builder

I have a filter query where it checks for three parameters id, keywords and status. It's working totally fine when I run this query in MySQL but when I try to run it through Laravel's query builder it's fetching all the results of that id.
Here is the query which I'm running in MySQL(and it's working fine like I mentioned):
SELECT * FROM `poems`
WHERE book_id = 2
AND p_english_keywords LIKE '%freedom%'
AND p_status = 1
And here is the Laravel's query builder code:
$poems = Poems
::where('book_id', '=', $filter, 'AND', 'p_english_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
->orWhere('book_id', '=', $filter, 'AND', 'p_spanish_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
->orWhere('book_id', '=', $filter, 'AND', 'p_german_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
->orWhere('book_id', '=', $filter, 'AND', 'p_urdu_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1)
->paginate(10);
This query looks totally fine and it's also working fine if a user removes the filter. It's searching for the keywords in user's language. But whenever a user applies a filter, it shows all the results from the filtered book instead of specific keywords in that book. Please Help!
I'm not sure why Poems::where('book_id', '=', $filter, 'AND', 'p_english_keywords', 'LIKE', '%'.$query.'%', 'AND', 'p_status', '=', 1) ever worked for you since that syntax is not in the documentation anywhere so I'm gonna rewrite your query.
$poems = Poems::where(function ($q) use ($filter, $query) {
$q->where([
['book_id', '=', $filter],
['p_english_keywords', 'like', '%'.$query.'%'],
['p_status', '=', 1],
]);
})
->orWhere(function ($q) use ($filter, $query) {
$q->where([
['book_id', '=', $filter],
['p_spanish_keywords', 'like', '%'.$query.'%'],
['p_status', '=', 1],
]);
})
->orWhere(function ($q) use ($filter, $query) {
$q->where([
['book_id', '=', $filter],
['p_german_keywords', 'like', '%'.$query.'%'],
['p_status', '=', 1],
]);
})
->orWhere(function ($q) use ($filter, $query) {
$q->where([
['book_id', '=', $filter],
['p_urdu_keywords', 'like', '%'.$query.'%'],
['p_status', '=', 1],
]);
})
->paginate(10);
However, since you always make the the same filters (book_id = $filter and p_status = 1), I think this can be reduced even further:
$poems = Poems::where([
['book_id', '=', $filter],
['p_status', '=', 1],
])
->where(function ($q) use ($query) {
$q->where('p_english_keywords', 'like', '%'.$query.'%')
->orWhere('p_spanish_keywords', 'like', '%'.$query.'%')
->orWhere('p_german_keywords', 'like', '%'.$query.'%')
->orWhere('p_urdu_keywords', 'like', '%'.$query.'%');
})
->paginate(10);
Using toSql(), I get the following query, which I think you're looking for:
select * from `poems`
where (
`book_id` = ? and `p_status` = ?
)
and (
`p_english_keywords` like ?
or `p_spanish_keywords` like ?
or `p_german_keywords` like ?
or `p_urdu_keywords` like ?
)

how to set count(*) as field name in laravel

I am using larvel eloquent.
i am using this query using model. My code is
$books = Book::select('title', 'author', Book::raw('count(*) as copies'))
->where('title', 'like', '%'.$name.'%')
->orWhere(function ($query) use ($name) {
$query->where('author', 'like', '%'.$name.'%')
->where('subject', 'like', '%'.$name.'%');
})
->groupBy('title','author')
->get();
I got the error
"strtolower() expects parameter 1 to be string, object given"
I know the error is in count(). The code
raw('count() as copies') is used in table.
But I dont know how to use count(*) as copies in model eloquent. My model name is Book.
One more doubt i have, can we use multple fields in groupBy, ie
groupBy('title','author')
use selectRaw()
$books = Book::select('title', 'author'))
->where('title', 'like', '%'.$name.'%')
->orWhere(function ($query) use ($name) {
$query->where('author', 'like', '%'.$name.'%')
->where('subject', 'like', '%'.$name.'%');
})
->selectRaw('count(*) as copies')
->groupBy('title','author')
->get();
Try this, SelectRaw
$books = Book::select('title', 'author')
->selectRaw('count(*) as copies')
->where('title', 'like', '%'.$name.'%')
->orWhere(function ($query) use ($name) {
$query->where('author', 'like', '%'.$name.'%')
->where('subject', 'like', '%'.$name.'%');
})
->groupBy('title','author')
->get();
You have this posiblity also
->select('title','author', DB::raw('count(*) as copies'))
Laravel Documentation Raw

Categories