【问题标题】:Laravel: Count number of rows in a relationshipLaravel:计算关系中的行数
【发布时间】:2018-03-14 18:05:01
【问题描述】:

我有以下关系:

  • 一个场地有很多优惠
  • 一个报价有多个订单

我有以下 Eloquent 模型来表示这一点:

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

我想使用 Laravel 的 Eloquent 模型来确定具有 location_id = 5 的场所的订单总数。

我设法做到这一点的唯一方法如下:

$venues = Venue::where('location_id', 5)->with('orders')->get();

$numberOfOrders = 0;
foreach($venues as $venue) {
    $numberOfOrders += $venue->orders->count();
}
dump($numberOfOrders); // Output a single number (e.g. 512)

但是,这显然不是很有效,因为我使用 PHP 而不是 SQL 来计算计数。

如何单独使用 Eloquent 模型来做到这一点。

【问题讨论】:

    标签: php laravel laravel-5 eloquent


    【解决方案1】:

    如果你使用 Laravel 5.3 或更高版本,你可以使用withCount

    如果你想计算一段关系的结果数 实际加载它们你可以使用 withCount 方法,这将 在结果模型上放置一个 {relation}_count 列。例如:

    $venues = Venue::withCount(['orders'])->get;
    
    foreach ($venues as $venue) {
        echo $venue->orders_count;
    }
    

    您可以在Laravel Documentation. 中阅读有关withCount 的更多信息

    如果您使用低于 5.3 的版本,您可以在 Venue 模型上创建自定义关系:

    public function ordersCount()
    {
        return $this->belongsToMany('App\Models\Order')
            ->selectRaw('venue_id, count(*) as aggregate_orders')
            ->groupBy('venue_id');
    }
    
    public function getOrderCount()
    {
        // if relation is not loaded already, let's do it first
        if (!array_key_exists('ordersCount', $this->relations)) {
            $this->load('ordersCount');
        }
    
        $related = $this->getRelation('ordersCount')->first();
        // then return the count directly
        return ($related) ? (int) $related->aggregate_orders : 0;
    }
    

    然后可以用作:Venue::with('ordersCount');。这种自定义关系的好处是您只查询计数,而不是在不需要时查询所有这些关系。

    【讨论】:

      【解决方案2】:
      $venues = Venue::with([
          'orders' => function ($q) {
              $q->withCount('orders');
          }
      ])->get();
      

      然后以这种方式使用它来获取单个记录

      $venues->first()->orders->orders_count();
      

      或者,您也可以将这种方式用于集合

      foreach($venues as $venue)
      {
      echo $venue->order_count;
      }
      

      【讨论】:

        【解决方案3】:

        您可以使用 Eloquent。从 Laravel 5.3 开始,有 withCount()

        在您的情况下,您将拥有

        $venues = Venue::where('location_id', 5)->with('orders')->withCount('orders')->get();
        

        那就这样访问吧

        foreach ($venues as $venue) {
            echo $venue->orders_count;
        }
        

        可以在这里找到参考:https://laravel.com/docs/5.3/eloquent-relationships#querying-relations

        【讨论】:

          猜你喜欢
          • 2017-06-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-23
          • 1970-01-01
          • 1970-01-01
          • 2016-04-07
          • 1970-01-01
          相关资源
          最近更新 更多