Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Laravel, can we sum related models attribute using withCount method?

Tags:

laravel

I have 3 models related like so : Prize -> TimeSlot -> Winner, with their corresponding relationship methods $prize->hasMany(TimeSlot) and $prize->hasManyThrough(Winner, TimeSlot).

I am trying to count in one eloquent query the number of winners and the number of time slots.

Here is the query :

$prizes = $prizes->withCount(['winners', 'timeSlots' => function ($query) {
    $query->sum('min'); // min is an attribute on TimeSlot
}])->get();

This gives me the number of winners with a winners_count attribute on each prize. I thought it would give me the 'sum number' of time slots for each prize but the query breaks on that part with an error like :

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'prizes.id' in 'where clause' 
(SQL: select sum(`min`) as aggregate from `time_slots` where `time_slots`.`prize_id` = `prizes`.`id`)

The documentation of withCount method only show how to constraint the query (with a where clause for example) but not with an aggregate like sum.

P.S: I already know how to do this with something like :

$prizes = $prizes->with('timeSlots')->withCount('winners')->get();

$numOfWinners = $prizes->sum('winners_count');

$numOfAvailablePrizes = $prizes->sum(function ($prize) {
    return $prize->timeSlots()->sum('min');
});

But i thought the version with one query would save me some useless loops...

Thanks for answers !

like image 914
B. Payoux Avatar asked Apr 29 '17 10:04

B. Payoux


People also ask

How to use withCount in Laravel?

How to use laravel withCount()? The values defined in the specified withCount() methods turn into the main object count. So here the user has to define $user -> total count of the post and $user -> total count of the feeds. All are defined as variables.

What is the use of whereHas in Laravel?

whereHas() works basically the same as has() but allows you to specify additional filters for the related model to check.

Has one through relationship Laravel?

Laravel introduces a relationship: “HasOneThrough”. This is new in Laravel Development but, other framework uses this like “Rails”. The “HasOneThrough” relationship links models through a single intermediate relation. For example, if each group will have users and users will have their users history.

How do you define a relationship in Laravel?

To define a relationship, we need first to define the post() method in User model. In the post() method, we need to implement the hasOne() method that returns the result. Let's understand the one to one relationship through an example. First, we add the new column (user_id) in an existing table named as posts.


1 Answers

Try this

$query->withCount(['timeSlots AS timeslots_sum' => function ($query) {
    $query->select(DB::raw('SUM(min) as timeslots_sum'));
}]);

It will returns

"timeslots_sum" => "123" // total
like image 147
Wahyu Kristianto Avatar answered Oct 18 '22 22:10

Wahyu Kristianto