MySQL AVG函数未返回全部记录问题排查
这个问题我太熟了!问题出在你用了聚合函数AVG(reviews.rating)但没加GROUP BY子句——MySQL碰到这种情况会默认把所有符合条件的行当成一个分组处理,自然就只返回一条聚合后的结果了。而你去掉AVG排序后,没有触发聚合逻辑,所以6条记录都能正常显示。
解决方案
要保留所有符合条件的服务记录,同时按经销商的平均评分排序,你需要明确告诉MySQL按服务的唯一标识分组。因为你要的是每个services条目对应的结果,所以用services.id作为分组依据最合理,这样每个服务会被当成独立分组,各自计算所属经销商的评分平均值。
修正后的SQL语句如下:
SELECT services.*, dealer.id AS dealerID, services.id AS serviceID, AVG(reviews.rating) AS avg_rating -- 显式查出平均评分,方便排序和查看 FROM services LEFT JOIN dealer ON services.dealer = dealer.id LEFT JOIN reviews ON reviews.dealer_id = dealer.id WHERE services.brand_id = '9' AND services.model_id = '107' AND services.petrol > 0 GROUP BY services.id -- 核心:按服务ID分组,确保每个服务单独计算平均评分 ORDER BY services.total ASC, avg_rating DESC;
补充细节
- 因为是
LEFT JOIN reviews,有些经销商可能没有任何评价,这时候AVG(reviews.rating)会返回NULL。如果希望没评分的经销商排在有评分的后面(或前面),可以用COALESCE(AVG(reviews.rating), 0)把NULL转为0,让排序逻辑更符合预期。 - 如果你的MySQL开启了
ONLY_FULL_GROUP_BY严格模式(默认开启),理论上需要把SELECT里所有非聚合的列都加到GROUP BY里,但因为services.id是services表的主键,其他services字段都依赖于它,所以仅按services.id分组在大多数场景下是合法的。
内容的提问来源于stack exchange,提问作者danny
相关产品推荐
相关产品推荐

