【问题标题】:How to do multiple aggregations in a "has through" relationship in a single query using Laravel?如何在使用 Laravel 的单个查询中以“通过”关系进行多个聚合?
【发布时间】:2018-03-23 20:46:10
【问题描述】:

我有以下表格:

场地

  • 身份证

优惠

  • 身份证
  • venue_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);
    }
}

我想运行一个查询,让我可以查看每个场地及其拥有的订单数量。例如

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 的功能。

【问题讨论】:

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


    【解决方案1】:

    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
        }
    }
    

    【讨论】:

    • 但我想总结数量
    • 这不是很有效,因为您必须获取所有订单然后执行循环。问题中的SQL直接返回总数。
    猜你喜欢
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2021-02-17
    • 2019-06-29
    • 2017-10-24
    • 2021-07-21
    • 2014-08-19
    相关资源
    最近更新 更多