Multiple value Search in Laravel Query Builder - mysql

Here is my code
$search_term = "Hary Kumar";
$filterData = DB::table('signups')->where('name','LIKE',"%{$search_term}%");
If I am not wrong above code will give me result like:
select * from signups where name like "%Hary Kumar%"
But, I am trying to get
select * from signups where name like "%Hary%" or name like "%Kumar%"

You are looking for a simple orWhere()
DB::table('signups')
->where('name', 'LIKE', "%{$first_term}%")
->orWhere('name', 'LIKE', "%{$second_term}%");

I got my answer. Here is the code:
$search_values = explode(" ",$search_term);
DB::table('signups')
->orWhere(function ($query) use($search_values) {
foreach($search_values as $search_value)
$query->orwhere('name', 'like', '%' . $search_value .'%');})

Related

laravel eloquent where and multiple or where

I'm using the Laravel Eloquent query builder and i want to have advance queries inside when clause
my eloquent :
bank::where('shop_id', $shopId)
->when(($search != ""), function ($query) use ($search) {
return $query->orWhere('bank_name', 'like', '%'.$search.'%')
->orWhere('account_name', 'like', '%'.$search.'%')
->orWhere('account_number', 'like', '%'.$search.'%');
})->toSql();
sql from eloquent :
select * from bank
where shop_id = 1
and bank_name like '%Bank%' or
account_name like '%Bank%' or
account_number like '%Bank%'
sql result that i want:
select * from bank
where shop_id = '1'
and (bank_name like '%Bank%' or
account_name like '%Bank%' or
account_number like '%Bank%')
i can use subquery but its not efficient.
You need to use the closure form of where around the or wheres:
bank::where('shop_id', $shopId)
->when(($search != ""), function ($query) use ($search) {
return $query->where(function ($query) use ($search) {
return $query
->orWhere('bank_name', 'like', '%'.$search.'%')
->orWhere('account_name', 'like', '%'.$search.'%')
->orWhere('account_number', 'like', '%'.$search.'%');
})
})
->toSql();

Laravel eloquent: Having and where in the same query but I want ti to be OR [duplicate]

Currently I am working on a project in Laravel but I am stuck.I want to create a SQL statement like this:
SELECT * FROM SPITems WHERE publisher_id=? AND feed_id=? AND (title LIKE '%?%' OR description LIKE '%?%')
Now I have this code:
$query = SPItem::orderBy('title');
if(isset($_GET['publisherID']) && is_numeric($_GET['publisherID']))
{
$query = $query->where('publisher_id', $_GET['publisherID']);
}
if(isset($_GET['productFeedID']) && is_numeric($_GET['productFeedID']))
{
$query = $query->where('program_id', $_GET['feedID']);
}
if(isset($_GET['search']))
{
$query = $query->orWhere('title', 'like', '%' . $_GET['search'] . '%');
$query = $query->where('description', 'like', '%' . $_GET['search'] . '%');
}
But that generates:
SELECT * FROM SPITems WHERE (publisher_id=? AND feed_id=?) OR (title LIKE '%?%') AND description LIKE '%?%'
How can I get the correct "or" order?
Check out the Logical Grouping section in the docs:
https://laravel.com/docs/master/queries#logical-grouping
It explains how to group conditions in the WHERE clause.
It should be something like:
if(isset($_GET['search']))
{
$query->where(function($query){
$query->where('title', 'like', '%' . $_GET['search'] . '%')
->orWhere('description', 'like', '%' . $_GET['search'] . '%');
});
}
You can use whereRaw
SPItem::whereRaw(" publisher_id=? AND feed_id=? AND (title LIKE '%?%' OR description LIKE '%?%')", array(?,?,?,?))

Query for returning individual records from related table in a polymorphic relationship

I'm currently working with an Activities table which has Thread and Replies records associated with it. When I try to join the tables, I get a mix and match and both records and it doesn't return individual records, but with records containing both Thread and Reply "body" field. I'm hoping someone can see what I'm trying to do with the code I'm providing:
if (request('name')){
$name = request('name');
$user = User::where('name', $name)->firstOrFail();
$activities = \DB::table('activities')
->leftJoin('threads', function($builder) use ($user){
$builder->on('threads.user_id', '=', 'activities.user_id')
->where('activities.user_id', '=', $user->id)
->where('activities.activity_type', '=', 'App\Thread');
})
->leftJoin('replies', function($builder) use ($user){
$builder->on('replies.user_id', '=', 'activities.user_id')
->where('activities.user_id', '=', $user->id)
->where('activities.activity_type', '=', 'App\Reply');
})
->where('replies.body', 'LIKE', '%' . $search . '%')
->orWhere('threads.title', 'LIKE', '%' . $search . '%')
->orWhere('threads.body', 'LIKE', '%' . $search . '%')
->get()->unique('id');
}
I want to return Threads and Replies separately with all the other fields, as sometimes in my experimentation it has led to the user being null or the body being null and I just don't understand why.
Sometimes it will return a App\Thread in the Activities table that I have created as an App\Reply. I'll admit my knowledge of joins is limited so I'm asking if anyone can please help!
I've got this new query here:
$activities = Activity::with('activity')->whereHas('thread', function ($query) use ($search, $user) {
$query->where('threads.user_id', '=', $user->id)
->where('threads.body', 'LIKE', '%' . $search . '%')
->orWhere('threads.title', 'LIKE', '%' . $search . '%');
})->orWhereHas('reply', function ($query) use ($search, $user) {
$query->where('replies.body', 'LIKE', '%' . $search . '%')
->where('replies.user_id', '=', $user->id);
})->get();
Thank you!
After trying to include the user in the query builder, I just added the user after my ::with clause and got the following query to work:
$activities = Activity::with('activity')->where('user_id', $user->id)->whereHas('thread', function ($query) use ($search, $user) {
$query->where('threads.body', 'LIKE', '%' . $search . '%')
->orWhere('threads.title', 'LIKE', '%' . $search . '%');
})->orWhereHas('reply', function ($query) use ($search, $user) {
$query->where('replies.body', 'LIKE', '%' . $search . '%')
->where('replies.user_id', '=', $user->id);
})->get();
Anyone in the future who may need some additional assistance can visit this link: https://zaengle.com/blog/using-wherehas-in-laravel-polymorphic-relations

Selecting to multiple tables in Laravel

Trying to select entries from user input $query. I would like to search the first_name, last_name, address (etc) columns that has NULL on deleted_at. What I have done so far is:
$data = DB::table('users')
->where('first_name', 'LIKE', '%' . $query . '%')
->orWhere('last_name', 'LIKE', '%' . $query . '%')
->orWhere('address', 'LIKE', '%' . $query. '%')
->whereNull('deleted_at')
->get();
My goal is to search the above mentioned columns by the user's query and show any match it finds. Problem is, it also shows entries that are NOT NULL in the column deleted_at. I wish to only see results which are NULL at deleted_at. What may I have been doing wrong?
make use of parameter grouping
$data = DB::table('users')
->whereNull('deleted_at')
->where(function ($query) {
$query->where('first_name', 'LIKE', '%' . $query . '%')
->orWhere('last_name', 'LIKE', '%' . $query . '%')
->orWhere('address', 'LIKE', '%' . $query. '%');
})
->get();

Search in model and in its relations and paginate results

So I'm building an ECommerce site using Laravel/MySQL, the product related tables I have are as follows: 'products', 'attributes', 'taxonomies' and 'tags'. When a user types a keyword to search for product, I want to search all 4 tables with one query to get the desired products, then I want to use Laravel paginate function to paginate the result, now how do I make it done in one query? Maybe some joins involved?
Here it is, the relationship of my database tables, as for my models, it is defined like this:
class Product extends Eloquent {
...
public function taxonomies() {
return $this->belongsToMany('Taxonomy', 'product_taxonomy', 'product_id', 'taxonomy_id');
}
...
// Same goes for attributes and labels
public function reviews() {
return $this->hasMany('Review', 'product_id');
}
}
Maybe you want something like this:
$products = Product::where('name', 'LIKE ', '%' . $keyword . '%');
$products = $products->orWhereHas('attributes',
function ($query) use ($keyword) {
$query->where('name', 'LIKE ', '%' . $keyword . '%');
}
);
$products = $products->orWhereHas('taxonomies',
function ($query) use ($keyword) {
$query->where('name', 'LIKE ', '%' . $keyword . '%');
}
);
$products = $products->orWhereHas('tags',
function ($query) use ($keyword) {
$query->where('name', 'LIKE ', '%' . $keyword . '%');
}
);
$products = $products->paginate(10);
Now you look in product name and in names of your relations (tags, taxonomies and attributes) and paginate 10 products.
You can try like this
$data = DB::table('products')
->join('attributes', 'products.attributes_id', '=', 'attributes.id')
->join('taxonomies', 'products.taxonomies_id', '=', 'taxonomies.id')
->join('tags', 'host_vulnerabilities.tags_id', '=', 'tags.id')
->where('products.id', '=', $id)
->select('products.id', 'attributes.name') //all required fields
->paginate(15);
I have just added sample example. Please update code as per your requirement
Use UNION for this,
SELECT product_id, product name FROM Products WHERE keyword = 'my_keyword' UNION
SELECT product_id, product name FROM Attributes WHERE keyword = 'my_keyword' UNION
..... Same for other tables
Moreover it will filter out repeated results as UNION works as UNION DISTINCT. But if you provide us with a schema or some db structure, can provide a better solution.
For Laravel, this may work you can create a view and query the view instead of the actual tables, or create your Paginator manually:
$page = Input::get('page', 1);
$paginate = 10;
$w1 = 'my_keyword';
$first = DB::table('products')->where('attribute', 'like', '"%'.$w1.'%"');
$second = DB::table('attributes')->where('attribute', 'like', '"%'.$w1.'%"');
$third = DB::table('taxonomies')->where('attribute', 'like', '"%'.$w1.'%"');
$fourth = DB::table('tags')->where('attribute', 'like', '"%'.$w1.'%"');
$union1 = $first->union($second);
$union2 = $third->union($union1);
$union3 = $fourth->union($union2);
$union3->get();
$slice = array_slice($union3, $paginate * ($page - 1), $paginate);
$result = Paginator::make($slice, count($union3), $paginate);
return View::make('yourView',compact('result'));