How to achieve sub collection on a collection of an array? - php

I want to get the detailed product of a collection from groupBy in laravel. How can I achieve that?
I'm using php 7.1 and Laravel. I can get the collection for the total report for year, month, and day.
But can I get detailed product of that collection ?
My query for getting the collection in the controller
$totalBelanjaTahun = DB::table('assets')
->select(DB::raw('EXTRACT(MONTH FROM belitanggal_assets) AS monthCoba, SUM(beliharga_assets) AS harga_beli'))
->where('belitanggal_assets', 'like', '%'.$tahun.'%')
->groupBy(DB::raw('monthCoba'))
->get();
return view('DilarangBuka.reportTotalBelanjaTahun', compact('totalBelanjaTahun', 'tahun', 'totalPertahun'));
How can I achieve get detailed of product of that array, not just get the date and the price? Thanks

Don't groupBy records in mysql, you will get first record of every groups.
Try to get them out.
$totalBelanjaTahun = DB::table('assets')
->select(DB::raw('EXTRACT(MONTH FROM belitanggal_assets) AS monthCoba, beliharga_assets AS harga_beli, field1, field2, field3'))
->where('belitanggal_assets', 'like', '%'.$tahun.'%')
->get();
And groups them by collect
collect($totalBelanjaTahun)->groupBy('monthCoba')
Hope this can help you.

Related

Laravel Query Buider Group By Not Getting All The Records

I am trying to get the data using groupBy on type field from my transaction table. I am using this query
DB::table($this->table)
->select()
->whereRaw($where['rawQuery'], isset($where['bindParams']) ? $where['bindParams'] : array())
->groupBy('type')
->get();
But it is not giving the complete records. There are more than 10 records in my table. But it is giving me only two. One for type=1 and another for type=2. It is selecting only on record from each type. I am expecting that i will get all the transactions based on condition grouped in two result set. Anyone know why it is happening?
Try to call Collection groupBy instead. Just put groupBy after get(). It should work.
DB::table($this->table)
->select()
->whereRaw($where['rawQuery'], isset($where['bindParams']) ? $where['bindParams'] : array())
->get()
->groupBy('type');
Faq::where('type','host')->get()->groupBy('category');

Prevent getting a duppicate data from the database in CodeIgniter

I'm trying to get data from the database filtered by some categories
This is my code in CodeIgniter
$this->db
->select('*')
->from($this->table)
->join('sites','sites.id = categories_by_site.site_id')
->where('categories_by_site.category_id', $categories[0])
->or_where('categories_by_site.category_id', $categories[1])
->order_by('id', 'ASC')
->get()
->result();
I simplify my code for the sake of this question, the above query take the categories as a search filter and used it to get result from the database.
There can be many categories filter to search at the same time, that's why I am using or_where() method.
The problem with this, when I got the result data, it has duplicate row of entries in object array.
Anyone can suggest how to prevent from getting a duppicate data from the database using above query?
Thanks
You can use group_by to solve this issue
Replace your code with
$this->db
->select('*')
->from($this->table)
->join('sites','sites.id = categories_by_site.site_id')
->where('categories_by_site.category_id', $categories[0])
->or_where('categories_by_site.category_id', $categories[1])
->order_by('id', 'ASC')
->group_by('categories_by_site.category_id')
->get()
->result();
You can eleminate duplicate values using distinct or group by
As you select all fields a group by is better in my opinion. Example to group by category_id
$this->db->group_by('category_id');

How can I retrieve the information I want using MySQL `joins` or Laravel `relationships`?

I am working on a project using the Laravel framework. In this project I have three tables:
1) Master Part Numbers (master_part_numbers)
Columns: id, part_number
Values: 1, MS26778-042
2) Inventory (inventory)
Columns: id, master_part_number, stock_qty
Values: 1, 1, 7
3) Inventory Min Maxes (inventory_min_maxes)
Columns: id, master_part_number, min_qty
Values: 1, 1, 10
I am trying to find the inventory where the stock level is below the min_qty. I have been attempting this using joins, like so:
$test = MasterPartNumber::table('master_part_numbers')
->join('inventory', 'master_part_numbers.id', '=', 'inventory.master_part_number_id')
->join('inventory_min_maxes', 'master_part_numbers.id', '=', 'inventory_min_maxes.master_part_number_id')
->select('master_part_numbers.part_number')
->where('inventory.stock_qty', '<=', 'inventory_min_maxes.min_qty')
->get();
However I am getting an empty collection every time. I have tried removing the where() clause and I get all the part numbers in the inventory, so it feels like I'm on the right track, but missing a critical component.
Also, I don't know if there is an easier or more efficient way to do this using Laravel's Eloquent Relationships, but that option is available.
Note: I added the space after table('master_part_numbers') in my query displayed here on purpose, for readability.
EDIT 1:
This sql query returns the expect result:
SELECT master_part_numbers.part_number
FROM master_part_numbers
JOIN inventory ON master_part_numbers.id=inventory.master_part_number_id
JOIN inventory_min_maxes ON master_part_numbers.id=inventory_min_maxes.master_part_number_id
WHERE inventory.stock_qty<=inventory_min_maxes.min_qty;
EDIT 2:
I finally got it working with some help from the Laravel IRC, however it isn't ideal because I am missing out on some of the data I would like to display, normally collected through relationships.
Here is what I am currently using, but I hope to get refactored:
DB::select(DB::raw('SELECT master_part_numbers.id, master_part_numbers.part_number, master_part_numbers.description, inventory.stock_qty, inventory.base_location_id, inventory_min_maxes.min_qty, inventory_min_maxes.max_qty
FROM master_part_numbers
JOIN inventory ON master_part_numbers.id = inventory.master_part_number_id
JOIN inventory_min_maxes ON master_part_numbers.id = inventory_min_maxes.master_part_number_id
WHERE inventory.stock_qty <= inventory_min_maxes.min_qty'));
If I have understood your problem correctly then
'masters_part_numbers.id' == 'inventory.id' and
'inventory.master_part_number' == 'inventory_min_maxes.master_part_number'
$test = DB::table('master_part_numbers')
->join('inventory', 'master_part_numbers.id', '=', 'inventory.id')
->join('inventory_min_maxes', 'inventory.master_part_number', '=', 'inventory_min_maxes.master_part_number')
->where('inventory.stock_qty', '<=', 'inventory_min_maxes.min_qty')
->whereNotNull('inventory_min_maxes.master_part_number');
->select(DB::raw('part_number'))
->get();
Based on above criteria. This code will work. I tried in laravel 5.4 .
Try and let me know. nd if it work give me a thumbs up
I discovered a way to solve this problem using the Laravel ->whereRAW() statement:
$test = $inventory->join('inventory_min_maxes', 'inventory.id', '=', 'inventory.inventory_min_max_id')
->whereRaw('inventory.stock_qty <= inventory_min_maxes.min_qty')
->whereRaw('inventory.inventory_min_max_id = inventory_min_maxes.id') // required so it tests against the specific record, without it will test against all records.
->get();
The major advantage for me, other than it looked terribly ugly before, was that I can now use the power of relationships.
Note: $inventory is an instance of my Inventory model, which I type hinted in the index() method.

Laravel eloquent difficult relation query

I'm a system for a friend, but stumbled across a little problem.
I've got 3 models (customerCard, customerCardComment and customerCardFollowup).
It's better if you see the image below to understand what I'm trying to achieve. As you see I'm trying to get a result where I get a customerCard model where the sold field is equal to 0 and the customerCard model has no customerCardComment model where the type field is equal to 1,2 or 3, and the customerCard also does not have any customerCardFollowup.
Databases:
customer_cards
customer_card_comments
customer_card_followups
Both comments and followups table are related to the ID field in customer_cards. Both have foreign keys customer_card_id.
Is there a way to do this query? Or am i lost?
Thanks in advance.
Laravel's whereHas accepts a 3rd and 4th parameter. The 3rd parameter is the comparison operator against the count of the result set, and the 4th argument is the number to compare against. This will solve the first problem:
CustomerCard::where(function($query){
$query->where('sold', 0)
->whereHas('customerCardComment', function($query){
return $query->whereIn('type', [1,2,3]);
}, '=', 0);
});
Next, you can use ->has() to count the number of records returned from a relation, this will solve your second problem:
CustomerCard::where(function($query){
$query->where('sold', 0)
->whereHas('customerCardComment', function($query){
return $query->whereIn('type', [1,2,3]);
}, '=', 0)
->has('customerCardFollowup', '=', 0);
});
The 3rd one is actually a bit more complex and I need to think about how to approach that a bit more. I'll answer now to get you going in the right direction and edit and update the post with the solution to the 3rd problem shortly.

Get Count in mysql query in laravel

I wants to select the count of votes got for each items.Following query works fine but there is a problem if there is no vote for an item then that item is not showing in result.I actually wants details of each items and votes.If there is no vote for an item it should be shown count zero.
How can i achieve it?
DB::table('wonders')
->leftjoin('vote','votes.wonderId','=','wonders.id')
->select('wonders.id','wonders.title',DB::raw('count(votes.vote) as votes'))
->get();
Try this
DB::table('wonders')
->leftjoin('vote','votes.wonderId','=','wonders.id')
->select('wonders.id','wonders.title',DB::raw('ifnull(count(votes.vote),0) as votes'))
->groupBy('wonders.id')
->get();
maybe you need to use iffnull,try this
DB::table('wonders')
->leftjoin('vote','votes.wonderId','=','wonders.id')
->select('wonders.id','wonders.title',DB::raw('ifnull(count(votes.vote),0) as votes'))
->get();
Try this
DB::table('wonders')
->leftjoin('vote','votes.wonderId','=','wonders.id')
->selectRaw('wonders.id','wonders.title',count(votes.vote) as votes)
->groupBy('wonders.id')
->get();

Categories