繁体   English   中英

Laravel 雄辩顺序按 hasMany 的总和或按加入

[英]Laravel eloquent order by sum of hasMany or by join

我想由那些最喜欢的人订购我的产品。 我有一张产品表,一张喜欢表和一张用户表。

这是我喜欢表的样子: id, user_id, product_id, value

value可以是1-1 ,等于一个喜欢或一个不喜欢。

在我的产品模型中,我定义了这些关系:

public function likes()
{
    return $this->belongsToMany('App\Models\User', 'products_likes', 'product_id', 'user_id')->withPivot('value')->withTimestamps();
}

public function productLikes()
{
    return $this->hasMany('App\Models\ProductLike');
}

但是,现在我想获得点sum最多的前 20 个产品。 这就是我试图解决这个问题的方式,但是,我无法解决我的问题......

$products = Product::select('products.*', DB::raw('SUM(products_likes.value) as sumLikes'))
            ->join('products_likes', 'products_likes.product_id', '=', 'products.id')
            ->orderBy('sumLikes', 'DESC')
            ->get();

然而,这导致了一个奇怪的 sql 分组问题:

QLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause (SQL: select `products`.*, SUM(products_likes.value) as sumLikes from `products` inner join `products_likes` on `products_likes`.`product_id` = `products`.`id` order by `sumLikes` desc) 

有谁知道我如何存档? 我想让我的数据库来执行订购工作,而不是 Laravel。 我也在这里找到了一些解决方案,但他们建议执行all()with("likes")查询,并在查询执行后使用sortByDesc此处)。 但这会降低性能。

亲切的问候

从 laravel 5.2 开始,你可以使用withCount方法添加一个 'likes_count' 子查询列,可以像这样自定义:

Product::query()
    ->withCount(['likes as sumLikes' => function ($query) {
        return $query->select(\DB::raw('SUM(products_likes.value) AS sumLikes'));
    }])
    ->orderBy('sumLikes', 'DESC')
;

通过自己编写子查询,可以在 Laravel 5.1 或更旧版本上获得类似的结果:

$subquery = ProductLike::query()
    ->selectRaw('SUM(product_likes.value) as sumLikes')
    ->whereRaw('product_likes.product_id = products.id')
;
Product::query()
    ->addSelect(DB::raw($subquery->toSql()))
    ->orderBy('sumLikes', 'DESC')
;

另一种方法是使用连接,就像您尝试使用的那样,但您需要按产品分组才能使其工作。

Product::query()
    ->addSelect(DB::raw('SUM(products_likes.value) as sumLikes'))
    ->join('products_likes', 'products_likes.product_id', '=', 'products.id')
    ->groupBy('products.id')
    ->orderBy('sumLikes', 'DESC')
;

根据您的数据库引擎,您可能需要在选择中指定列,并按每列进行分组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM