如何在"中通过"进行多个聚合。使用Laravel在单个查询中建立关系?

时间:2018-03-15 12:01:02

标签: laravel laravel-5 laravel-5.1 laravel-eloquent

我有以下表格:

场地

  • ID

优惠

  • ID
  • venue_id

订单

  • ID
  • offer_id

场地可以提供很多优惠,优惠可以有很多订单。这些都是在适当的Eloquent模型中建模的,如下所示:

class Venue extends Model
{
    public function offers()
    {
        return $this->hasMany(Offer::class);
    }
}

class Offer extends Model
{
    public function orders()
    {
        return $this->hasMany(Order::class);
    }
}

我想运行一个查询,这样我就可以查看每个场所及其拥有的订单数量。 e.g。

venue_id | number_of_orders
---------------------------
5        | 20
15       | 0
8        | 123

我很容易使用原始SQL这样做:

select venues.id, sum(offersGrouped.number_of_orders) as total_number_of_orders
from venues
left outer join (
   select offers.id, offers.venue_id, sum(orders.quantity) as number_of_orders
   from offers
   left outer join orders on offers.id = orders.offer_id
   group by offers.id
) offersGrouped on venues.id = offersGrouped.venue_id
group by venues.id;

但是,如何使用Eloquent做同样的事情?

我正在使用Laravel 5.1,但如果需要,如果答案使用较新版本的Laravel功能,我不介意。

1 个答案:

答案 0 :(得分:0)

为您的HasManyThrough模型添加Venue关系:

public function orders()
{
    return $this->hasManyThrough(Order::class, Offer::class);
}

然后你可以这样做:

$venues = Venue::with('orders')->get();
foreach($venues as $venue) {
    // $venue->orders->sum('quantity')
}

或数据库内解决方案:

public function orders()
{
    return $this->hasManyThrough(Order::class, Offer::class)
        ->groupBy('venue_id')->selectRaw('SUM(quantity) sum');
}

$venues = Venue::with('orders')->get();
foreach($venues as $venue) {
    if($venue->orders->isNotEmpty()) {
        // $venue->orders->first()->sum
    } else {
        // 0
    }
}