【问题标题】:Laravel return restaurants with their rate averageLaravel 以平均价格返回餐厅
【发布时间】:2019-08-20 21:25:04
【问题描述】:
<?php

$query = $this->restaurant->leftJoin('reviews', 'reviews.restaurant_id', '=', 'restaurants.id');
$query = $user_id == null ? $query : $query->where("user_id", $user_id);

$query = $query->select('restaurants.*')
    ->selectRaw('ROUND(AVG(reviews.rating), 1) as average_rating')
    ->groupBy('restaurants.id')
    ->havingRaw('AVG(reviews.rating) >= ?', [$request->from_rating])
    ->havingRaw('AVG(reviews.rating) <= ?', [$request->to_rating])
    ->orderByDesc("average_rating")
    ->paginate(
        $this->perPage,
        ['id', 'name', 'image', 'description', 'filesystem', 'created_at'],
        'page',
        $request->page
    );

return $query;

我的查询如下所示。我有两张桌子:餐厅和评论。评论表存储restaurant_id。例如,当我们有 10 家餐厅并且我们只有其中一家餐厅有 1 条评论时,就会出现问题。运行此查询后,仅返回 1 家餐厅,因为我使用 havingRaw 根据平均评分过滤餐厅。因此,如果一家餐厅没有任何评级,则该餐厅不会被退回。 如何使所有餐厅仍然返回,但他们的平均评分变为 0?

【问题讨论】:

  • 如果你使用 Eloquent 并以 Laravel 的方式做事,这一切可能会容易得多? Here's an example doing something similar 看起来很整洁,也许有帮助。链接的博客文章阐明了他在做什么,值得一读。
  • 或者,不要在查询中进行评级过滤(删除havingRaw()s),而是使用filter the returned collection?如果处理大量结果集,可能效率不高。
  • 问题是我按照你的建议让它工作,但我也想按平均评级过滤。您的链接不包含该功能,这就是为什么我也无法使其工作。
  • 当然可以 - Restaurant::with('avgRating')-&gt;get()-&gt;filter();
  • 我讨厌 filter() 函数。它适用于集合,比数据库查询慢。

标签: laravel


【解决方案1】:

您可以使用 CASE WHEN 以更具体的条件填充 mysql。您也可以将 'rating' 表的数据类型更改为 int(5),在这种情况下,所有的空值都将显示为 0。所以这将根据您的问题进行。

【讨论】:

    猜你喜欢
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多