Laravel 使用带外键的 avg() 函数

Laravel using avg() function with foreign key

我想获得每个产品的平均费率。

我有一个 rates table,它有一个指向 product table 的外键, rates table 与此类似

当我尝试使用此代码获取产品时:

$stocks = Stocks::with('images:url,color', 'tags:tag', 'sizes', 'rates')
                ->get()
                ->pluckDistant('tags', 'tag')
                ->pluckDistant('sizes', 'size');

它returns这个

[
    {
        "id": 10,
        "name": "name",
        "image": "1564964985mI7jTuQEZxD49SGTce6Qntl7U8QDnc8uhVxedyYN.jpeg",
        "images": [
            {
                "url": "1564964985mI7jTuQEZxD49SGTce6Qntl7U8QDnc8uhVxedyYN.jpeg",
                "color": ""
            },
            {
                "url": "1564964985EV20c1jGvCVCzpCv2Gy9r5TnWM0hMpCBsiRbe8pI.png",
                "color": ""
            },
            {
                "url": "1564964985iFcMox6rjsUaM8CHil5oQ9HkrsDqTrqLNY1cXCRX.png",
                "color": ""
            }
        ],
        "tags": [
            "عطور"
        ],
        "sizes": [],
        "rates": [
            {
                "id": 1,
                "stocks_id": 10,
                "rate": 2
            },
            {
                "id": 2,
                "stocks_id": 10,
                "rate": 4
            }
        ],
    }
]

如何使用 eloquent 关系获得 "rates":3 的平均速率,从而通过 sql 得到它们而不用 php 处理?

您可以只使用连接并在速率上使用聚合函数 table。

Stocks::with('images:url,color', 'tags:tag', 'sizes')
 ->join('rates', 'rates.stocks_id', '=', 'stocks.id')
 ->selectRaw('stocks.*')
 ->selectRaw('AVG(rates.rate) as average_rating')
 ->selectRaw('tags.*')
 ->selectRaw('sizes.*')
 ->selectRaw('images.*')
 ->groupBy('stocks.id')
 ->get()

您可以利用 Appending 之类的东西。假设您有一个 Product 模型,它与 Rate 模型有 OneToMany 关系。

您的 Product 模型看起来像这样:

class Product extends Model
{
    protected $with = ['rates'];


    protected $appends = ['average_rate'];


    public function getAverageRateAttribute()
    {
        return $this->attributes['average_rate'] = $this->rates->avg('rate');
    }

    public function rates() {
        return $this->hasMany(Rate::class);
    }
}

现在,无论何时从数据库中查询产品,结果都会附加费率。

array:7 [▼
  "id" => 1
  "created_at" => "2019-08-12 14:08:09"
  "updated_at" => "2019-08-12 14:08:09"
  "average_rate" => 4.5
  "rates" => array:2 [▶]
] 

但是,请注意导致 n+1 问题。如果您使用这种方法,请确保始终预加载您的 rates.