You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel查询问题:返回所有餐厅并将无评分餐厅平均评分为0

解决方法

要让所有餐厅都返回,并且把无评论餐厅的average_rating设为0,你需要做两个关键调整:

  1. 用COALESCE()函数把AVG(reviews.rating)的NULL值转换成0,这样无评论的餐厅平均分会被计算为0。
  2. 在havingRaw条件中也使用COALESCE(),确保0值能被你的评分范围过滤逻辑包含进去。

修改后的完整查询代码如下:

<?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(COALESCE(AVG(reviews.rating), 0), 1) as average_rating')
    ->groupBy('restaurants.id')
    ->havingRaw('COALESCE(AVG(reviews.rating), 0) >= ?', [$request->from_rating])
    ->havingRaw('COALESCE(AVG(reviews.rating), 0) <= ?', [$request->to_rating])
    ->orderByDesc("average_rating")
    ->paginate(
        $this->perPage,
        ['id', 'name', 'image', 'description', 'filesystem', 'created_at'],
        'page',
        $request->page
    );

return $query;

为什么这样有效?

  • 你的原始查询中,没有评论的餐厅的AVG(reviews.rating)结果是NULL,而NULL在比较运算(>=/<=)中会返回false,所以这些餐厅被havingRaw过滤掉了。
  • COALESCE(AVG(reviews.rating), 0)会把NULL替换成0,这样无评论餐厅的平均分会被设为0,同时在having条件中,0会参与评分范围的判断(只要你的from_rating≤0且to_rating≥0,这些餐厅就会被保留)。

额外提示

如果你的评分范围可能不包含0(比如用户筛选的是1-5分),那无评论的餐厅还是会被过滤掉——这符合业务逻辑,但如果你希望无论评分范围如何都返回所有餐厅,那你需要调整having条件,把COALESCE(...)的判断改成:要么符合评分范围,要么原始的AVG(reviews.rating)是NULL(也就是无评论)。比如:

->havingRaw('(COALESCE(AVG(reviews.rating), 0) >= ? AND COALESCE(AVG(reviews.rating), 0) <= ?) OR AVG(reviews.rating) IS NULL', [$request->from_rating, $request->to_rating])

这样无论用户筛选的评分范围是什么,无评论的餐厅都会被返回,且平均分为0。

内容的提问来源于stack exchange,提问作者Nika Kurashvili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:34:10