Laravel 5.4 Query Builder Implementing orderBy with groupBy - php

I wanted to manipulate how data will be shown with cost layering methods such as LIFO and FIFO.
To get things started, here's my query:
$items = Inventory::whereActive('1')
->where('quantity', '>', 0)
->where(function($query) use($request) {
$query->where('name', 'LIKE', '%'.$request->search.'%')
->orwhere('ref_code', 'LIKE', '%'.$request->search.'%');
})->orderBy('created_at', 'dsc')
->groupBy('ref_code')
->get();
I wanted to use groupBy with ref_code so it will only show one data with the same ref_code, and I used orderBy with created_at and dsc for descending so that one data that will be shown will be the last one that was added. (Well, that's what I think that would happen).
But unfortunately, when I used groupBy, it only shows the first added data. How can I select the last data? I thought orderBy was gonna do the job but it didn't.

You can use an alternative way for this. If you have auto incrementing primary key as id then you can do it like,
$ids = Inventory::whereActive('1')
->where('quantity', '>', 0)
->where(function($query) use($request) {
$query->where('name', 'LIKE', '%'.$request->search.'%')
->orwhere('ref_code', 'LIKE', '%'.$request->search.'%');
})
->select('ref_code',\DB::raw('MAX(id) as ID'))
->groupBy('ref_code')
->pluck('ID');
Now, Get Items as
$items = Inventory::whereIn('id',$ids)->get();
Hence you will get your desired result.

Related

Laravel 9 - Eloquent group results of query

I am looking for a way to take one query in Eloquent to get all search results, and then take those results, group them by type, and output the different types.
I currently have this setup to get all my search results:
$listings = Listing::where('listings.expiration_date', $date_operator, date('Y-m-d H:i:s'));
$listing->where(function($query) use ($keyword) {
$query->where('listings.lot_number', 'LIKE', '%'.$keyword.'%')
->orWhere('listings.title', 'LIKE', '%'.$keyword.'%')
->orWhere('listings.brand', 'LIKE', '%'.$keyword.'%')
->orWhere('listings.grade', 'LIKE', '%'.$keyword.'%')
->orWhere('listings.tags', 'LIKE', '%'.$keyword.'%')
->orWhere('listings.player', 'LIKE', '%'.$keyword.'%');
})->leftJoin('bids', function($join){
$join->on('bids.listing_id', '=', 'listings.id')
->on('bids.id', '=', DB::raw("(select max(id) from bids WHERE bids.listing_id = listings.id)"));
})->leftJoin('media', function($join) {
$join->on('media.listing_id', '=', 'listings.lot_number')
->where('media.group_order', '=', '1')->groupBy('media.group');
});
$listings = $listings->get();
The resulting $listings shows all the search results that I want to appear. Each listing has a specific type (item_type) assigned to them (i.e. Card, Ball, Bat, etc). I'd like to take all those results and group the types so that I can get a unique list of types to display in the menu. I've tried GroupBy on the Collection but that doesn't seem to be working.
Thank You
Use the power of collections
$itemTypes = $listings->pluck('item_type')->unique()
// if item type is a sub array / relationship then you will need to use dot notation
So we are plucking only the 'item_type' field, removing all duplicates by using the unique method and you should then have a collection of unique item_type's

How to search from multiple tables in laravel?

How can I search from multiple tables using laravel eloquent. below is my query.
$data= User::where('id',$search_str)
->orWhere('name', 'LIKE', "%{$search_str}%")
->with('usersecond:id,name,email')->get();
If I search for something I get results from the user table. how can I get results from usersecond table in this query?
use whereHas() function
$data = User::where('id', $search_str)
->orWhere('name', 'LIKE', "%{$search_str}%")
->with('usersecond:id,name,email')
->orWhereHas('usersecond', function ($q) use ($search_str) {
$q->where('name', 'LIKE', "%{$search_str}%");
})->get();
ref link https://laravel.com/docs/7.x/eloquent-relationships#querying-relationship-existence

How to get first entry from the record in Laravel relation?

I got this query, it fetch results from my database, based on relationships.
The query works fine, but it grabs the first entry from the database/table and not the first value of the array.
How can I fix that?
$motor = Motor::query()
->where([
['effect_id', '=', $request->effect_id],
['poles', '=', $request->poles],
['voltage_id', '=', $request->voltage_id],
['active', '=', 1],
])
->whereHas('MotorSize', function (Builder $query) {
$query->whereIn('mounting', ['B5', 'B14', 'B34', 'B35']);
})
->firstOrFail();
I have tried different things, such as:
Adding the orderBy to the Motor model and created a "priority" field in my database, giving each a number between 1 and 100:
(i actually thought this would work, but it still grabs the first entry from the table)
public function MotorSize()
{
return $this->belongsTo('App\MotorSize')->orderBy('priority', 'ASC');
}
I also tried something like this, but it's a mess and never got it to work:
$query->where(function ($query) {
$query->where('mounting', 'like', 'B5');
})
->orWhere(function($query) {
$query->where('mounting', 'like', 'B14');
})
->orWhere(function($query) {
$query->where('mounting', 'like', 'B34');
})
->orWhere(function($query) {
$query->where('mounting', 'like', 'B35');
});
Any suggestions will be welcome :)

Multiple like in a laravel mongo db package not working

I have a project which is creating in laravel and mongodb. I am using a package for connecting to mongodb "https://github.com/jenssegers/laravel-mongodb". I have a table listing. In this table listing there is a text box for search data. For that I used like feature. I have followed the same in documentation but not working. When I search invoice_number data is getting empty. But when I search beds data is getting perfectly. Please correct me.
$bookings = Booking::select('invoice_number', 'temp_user_id', 'user', 'checkin_from', 'reserve_to', 'beds', 'dormitory', 'sleeps', 'status', 'payment_status', 'payment_type', 'total_prepayment_amount', 'txid')
->where('is_delete', 0)
->where('invoice_number', 'like', "%{$search}%")
->orWhere('beds', 'like', "%{$search}%")
->skip($start)
->take($limit)
->orderBy($order, $dir)
->get();
The WHERE statements in your query translate to this:
WHERE [cond_1] AND [cond_2] OR [cond_3]
I doubt this is the condition you need. I'd say you want this:
WHERE [cond_1] AND ([cond_2] OR [cond_3]) -- notice the brackets.
To achieve this, you need a closure in your Builder query. Try this:
$bookings = Booking::select('invoice_number', 'temp_user_id', 'user', 'checkin_from', 'reserve_to', 'beds', 'dormitory', 'sleeps', 'status', 'payment_status', 'payment_type', 'total_prepayment_amount', 'txid')
->where('is_delete', 0)
->where(function($query) use ($search) { /* That's the closure */
$query->where('invoice_number', 'like', "%{$search}%")
->orWhere('beds', 'like', "%{$search}%");
})
->skip($start)
->take($limit)
->orderBy($order, $dir)
->get();
And an example from the docs.

Laravel - Query Model if values contain a certain string (taken from search input)

I am implementing a search using Laravel and Ajax. So I have a Product which belongs to a Tag and a Subcategory. On the other hand the Subcategory belongs to a Category. I want to check all of their properties (field values) and check if they contain the given string. With some searching I found out that I have to use LIKE. Here is what I tried:
$products = Product::where('name_en', 'LIKE', $search)->get();
However this will get the products if the search string matches exactly the value. I want to match if it contains it. How can I proceed with the belongsTo relationships? How can I check the propreties of Tag and Subcategory as well? How to chain everything together so I achieve the desired result? Thanks in advance.
you are doing one thing wrong, your query returns you exact matches because you given the exact string. But your query should be like this.
$products = Product::where('name_en', 'LIKE', '%'.$search.'%')->get();
Above query will gives your products which contains the searched string.
And if you want to search in relational tables then you can user laravel method join(). But there are one more method whereHas but I always avoiding this method, because it creates very complex query. which is very heavy. So you can use join() method which will add inner join with relational table.
Here is the example of join:
$products = Product::join('tags', function($builder) {
$builder->on('tags.id', '=', 'products.tag_id');
// here you can add more conditions on tags table.
})
join('sub_categories', function($builder) {
$builder->on('sub_categories.id', '=', 'products.tag_id');
// here you can add more conditions on subcategories table.
})
->where('name_en', 'LIKE', '%'.$search.'%')
->get();
This is the basic example, you can use this according to your requirement.
To add to Lakhwinder Singh’s answer, it might be worth wrapping it up in a scope that you can apply to your model:
class Product extends Model
{
public function scopeSearch($query, $keywords)
{
return $query->where('name_en', 'LIKE', '%'.$keywords.'%');
}
}
You can then use this scope like this:
$products = Product::search($keywords)->get();
Which means you don’t have to keep manually adding “LIKE” conditions throughout your application.
As an aside, Laravel’s introducing Scout, a driver-based full text search extension for Eloquent, in version 5.3.
What you want is to write an advanced query to search product based on related models too, so as previous suggestion by others, you have to write join statements.
Check my example code below, which is written to search members, the search string also will bring members if the string matches, members skills or positions, so this will surely help you.
$users = User::select('app_users.*')
->distinct()
->join('app_members', 'app_users.id', '=', 'app_members.app_users_id')
->leftJoin('app_members_jobtitles', 'app_members.id', '=', 'app_members_jobtitles.app_members_id')
->leftJoin('app_jobtitles', 'app_members_jobtitles.app_jobtitles_id', '=', 'app_jobtitles.id')
->leftJoin('app_members_tags', 'app_members.id', '=', 'app_members_tags.app_members_id')
->leftJoin('app_technologies', 'app_members_tags.app_technologies_id', '=', 'app_technologies.id')
->whereNull('app_users.activation')
->where('app_users.block','=',0)
->where(function ($query)use ($search) {
$query->orWhere('app_users.first_name', 'like', '%'.$search.'%')
->orWhere('app_users.last_name', 'like', '%'.$search.'%')
->orWhere('app_members.company', 'like', '%'.$search.'%')
->orWhere('app_members.job_title', 'like', '%'.$search.'%')
->orWhere('app_jobtitles.title', 'like', '%'.$search.'%')
->orWhere('app_technologies.title', 'like', '%'.$search.'%')
->orWhere('app_members.summary', 'like', '%'.$search.'%');
})
->get();
Note the following join in the above code, which is in your case category and sub category
->leftJoin('app_members_jobtitles', 'app_members.id', '=', 'app_members_jobtitles.app_members_id')
->leftJoin('app_jobtitles', 'app_members_jobtitles.app_jobtitles_id', '=', 'app_jobtitles.id')

Categories