Eloquent Aggregates - laravel

Hi i have that query is it possible to insert additional count that counts self the Customer table rows? something like {{count($customers)}}
Also i have join the Services table on model, how can i add SUM on specific column of services table on the query above?
for example Service->sum('price');
$customers = Customer::query((['id', 'name', 'plate']))
->search($this->search,['id', 'name', 'plate'])
->withCount('services')
->orderBy($this->sortBy,$this->sortDirection,['id', 'name', 'plate'])
->paginate($this->perPage,['id', 'name', 'plate']);
return view('livewire.customers.show',['customers'=>$customers])

You do not need to change anything. The paginator already knows the total count.
$customers->total() should give you the count you're looking for.
As for the sum on a related column, Laravel added somewhat recently the withAggregates functions (withSum, withAvg). You should be able to get the total price by adding
->withSum('services as total_price', 'price')
to your query

Related

How Query Multiple dataset in Laravel

I am struggling to get list of places that matches current category(multiple dataset) and city:
what i did is the following,
$cat = Category::find($request->category_id)->toArray();
$cat_id = $cat['id'];
and
$places = DB::table('places')
->where('category',$cat_id)
->where('city_id', $request->city_id)
->get();
See screenshot of the dataset:
Data in the database
For your current problem, you can use the LIKE operator.
$places = DB::table('places')
->where('category','LIKE', '%"'.$cat_id.'"%')
->where('city_id', $request->city_id)
->get();
but the above code will not solve your problem permanently. It looks like you are trying to create a many to many relationship in this case the best practice to use pivot tables for this. Better if you could update the schema as an example and follow the Laravel standards to achieve this. Example:
table: category_place , having columns ["category_id", "place_id"]
in the same way, you need to update the following schema
Place Type
table: place_place_type, columns ["place_id", "place_type_id"]
Amenities
table: amenity_place, columns ["amenity_id", "place_id"]
Ref. link: https://laravel.com/docs/8.x/eloquent-relationships#many-to-many-polymorphic-relations

Laravel - How to paginate united Many To Many(Polymorphic) collection?

Trying to figure out how to fetch two related models(obviously united) of my Many To Many(Polymorphic) relationship.
What we have:
3 models: Bucket, Template and DesignPack.
Bucket has Many-To-Many(Polymorphic) relationship with Template and DesignPack(It means we have pivot table bucketables).In essence Bucket can have(be related with) both: Template and DesignPack.
Laravel 6.*
What I want to get:
I want to get a Bucket templates and design packs united in one collection and paginated!
Please check one of the solutions I've tried:
$templates = Bucket::find($bucket_id)->templates()->select(['id', 'file_name as name', 'size', 'preview']);
$design_packs = Bucket::find($bucket_id)->dps()->select(['id', 'name', 'size', 'preview']);
$all = $templates ->union($design_packs )->paginate(10);
Unfortunately that solution throws me the error(thought I checked what each request returns and it returns the same fields, not different):
"SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns (SQL: (select `id`, `size`, `preview`, `bucketables`.`bucket_id` as `pivot_bucket_id`, `bucketables`.`bucketable_id` as `pivot_bucketable_id`, `bucketables`.`bucketable_type` as `pivot_bucketable_type` from `design_packs` inner join `bucketables` on `design_packs`.`id` = `bucketables`.`bucketable_id` where `bucketables`.`bucket_id` = 3 and `bucketables`.`bucketable_type` = App\DesignPack and `design_packs`.`deleted_at` is null) union (select `id`, `size`, `preview` from `templates` inner join `bucketables` on `templates`.`id` = `bucketables`.`bucketable_id` where `bucketables`.`bucket_id` = 3 and `bucketables`.`bucketable_type` = App\Template and `templates`.`deleted_at` is null))"
Are there any different way to get what I want?
May be examples, documentation links or any helpful ideas?
Will be so grateful guys for any help!
Thank you!
You can pass closure to queries:
$templates = Bucket::whereHas('templates', function($query) use $bucket_id {
$query->where('bucket_id', $bucket_id);
})->get();
$designPacks = Bucket::whereHas('dps', function($query) use $bucket_id {
$query->where('bucket_id', $bucket_id);
})->get();
then merge 2 eloquent collections:
$mergedCollections = $templates->merge($designPacks);
now you have a collection of both results, you can select specific fields, limit the results or etc. you may want take a look at Laravel collection helpers.
also if you insist to use the union, you may want to take a look at this treat:
The used SELECT statements have a different number of columns (REDUX!!)

How to get sum along with this Laravel Eloquent query

Database Structure:
Table: sales_payments
columns: id, payer_id, payment_status, amount , ...
Please see this eloquent query. it's working fine but now i need the sum of amount key along with this given eloquent query and where conditions.
$query = SalesPayment::with(['abc.xyz'])
->whereHas('abc.xyz', function ($query) use ($options) {
$query->where('xyz_id',$options['xyz_id']);
});
$query->where(['key3' => key3(), 'payment_status' => PAYMENT_STATUS_SUCCESS]);
$query->orderBy('created_at', 'desc');
return $query->paginate(config('constants.PAGE_LIMIT'));
Possible Solution
Just put a select as mentioned below
$query = SalesPayment::select('*', \DB::raw('SUM(amount) AS total_sale_amount')->with ....
I have tested this solution it's working fine.
Please let me know if there is a better solution than this. And I'm looking for some other solutions Also.
Edit: But there is one problem with this solution that it returning me only one record when i put aggregate function (sum) in select otherwise it was returning more than one records.
You could use the sum method on the query.
$amount = $query->sum('amount');
A new query with the same conditions will be executed to calculate the sum of a column.
https://laravel.com/docs/6.x/queries#aggregates

Using Laravel Eloquent to count how many times something exists in an efficient manner

I have a table called rentals, within each row are columns state,city,zipcode which all house ids to another table with that info. There are about 3400 rentals. I am pulling each column to display the states,city and zipcode distinctly. I need to show how many rentals are in each one. I am doing this now via ajax, the person starts typing in what they want to see and it auto completes it with the count, but its slow because of the way im doing it.
$rentals_count = Rentals::where('published',1)->get();
foreach($states as $state) {
echo $state.”-“.$rentals_count->where(‘state’,$state->id)->count();
}
Above is roughly what im doing with pieces removed because they are not related to this question. Is there a better way to do this? It lags a bit so the auto complete seems broken to a new user.
Have you considered Eager loading your eloquent query? Eager loading is used to reduce query operations. When querying, you may specify which relationships should be eager loaded using the with method:
$rental_counts = Rentals::where('published',1)->with('your_relation')->get();
You can read more about that in Laravel Documentation
$rentals = Rentals::wherePublished(true)->withCount('state')->get();
When you loop through $rentals, the result will be in $rental->state_count
Setup a relation 'state' on rentals then call it like this
$rentals_count = Rentals::where('published',1)->with('state')->get()->groupBy('state');
$rentals_count->map(function($v, $k){
echo $v[0]->state->name .' - '. $v->count();
});
Meanwhile in Rentals Model
public function state(){
return $this->hasOne(State::class, 'state'); //state being your foreign key on rentals table. The primary key has to be id on your states table
}

Laravel Eloquent duplicate distinct row

Let's consider the image above. I would like to show duplicated entries as one entry and also I want to show the sum of the "stock" column. In this case it should be 5722.
Is it possible to do it using Eloquent? Or what are the best ways to do it?
Not sure how your database / query is built but you could maybe use something like that:
Item::groupBy('item_name')
->selectRaw('*, sum(stock) as sum')
->get();
It will return a collection of Item with an additional “sum” field
This will group the result with same medicine and supplier name and sum up the stock.
$result = Model_Name::groupBy('medicine_name','supplier_name')
->selectRaw('*, sum(stock) as sum')
->get();
Try this. Hope it might help you.

Resources