【问题标题】:Laravel sort by average of property of relationshipLaravel 按关系属性的平均值排序
【发布时间】:2021-10-10 19:33:07
【问题描述】:

我想知道 Eloquent 是否可以实现我想要实现的目标。假设您有一个带有 Comments 模型关系的 Post 模型,并且 Comment 模型具有 votes 属性。

我知道您可以通过以下方式获得带有评论计数的帖子集合:

$posts = Post::withCount('comments')->get();

这是对关系应用投票过滤器的方法:

$posts = Post::whereHas('comments', function (Builder $q, $vote_count) {
  $q->where('votes', '>=', $vote_count);
});

但我想做的,最好是在一个查询中,过滤(使用where())和排序(使用orderBy())帖子集合的平均投票分数。

要获得 one Post 的平均值,我首先会得到 sum('votes') 的总和,然后将其除以 withCount('comments') 以获得平均值。

但我想知道是否可以为集合制作一个过滤器,全部在一个查询中,过滤平均投票分数。

【问题讨论】:

  • 您可以使用Post::withCount(['comments as comments_avg_votes' => function($query) { $query->select(DB::raw('avg(votes)')); }])->get(); 获得 Post cmets 平均票数。但我不明白你要过滤什么
  • 谢谢。因此,通过您的查询,您现在获得了平均票数。在这个平均值上,我想做 1)一个 where 在那个平均值上,这样你就可以获得所有连接的 cmets 的平均票数大于某个值的帖子和 2)一个 orderBy 那个平均值,以便您可以根据连接的 cmets 的平均投票数对帖子进行排序。
  • 啊,我现在看到我可以将comments_avg_votes 传递给whereorderBy,太棒了!随意添加您的评论作为答案,我会接受它。
  • 最后一个:orderBy 有效,但where 无效,它给出了Unknown column 'comments_avg_votes' in 'where clause'
  • 是的,我运行了迁移。确实你是对的,一切都按预期工作,我在这里创建了一个新的沙箱,你可以在其中看到它:phpsandbox.io/n/…。在我自己的应用程序中它不起作用,所以我必须弄清楚为什么会这样,因为我使用几乎完全相同的查询和结构......请随时添加您的建议作为答案,我会接受它,我会试着弄清楚为什么它对我不起作用。

标签: laravel


【解决方案1】:

您可以通过以关系名称作为键、匿名函数作为值的数组来获取 Post cmets 投票平均值。在函数内部,您可以执行selectRaw 查询votes 列的平均值。然后,您将可以使用该“列”(实际上是别名)来执行 whereorderBy

$value = 5;
Post::withCount(['comments as comments_avg_votes' => function($query) {
        $query->select(DB::raw('avg(votes)'));
    }])
    ->where('comments_avg_votes', '>', $value)
    ->orderByDesc('comments_avg_votes')
    ->get();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 2018-01-07
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    相关资源
    最近更新 更多