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

如何通过一次数据库查询按评分统计评论数 无需服务端额外计算

完全可以,你可以直接通过数据库查询完成所有统计计算,无需拉取全量评论数据到服务端再处理,性能提升非常明显,以下是两种常用实现方案:

方案1:按评分分组统计

先通过分组查询拿到每个评分对应的评论数量,再自行取值计算:

// 查询返回以评分为键、对应评论数为值的集合
$ratingStats = Review::query()
    ->selectRaw('rating, COUNT(*) as count')
    ->where('product_id', $data['product_id'])
    ->whereNotNull('published_at')
    ->groupBy('rating')
    ->pluck('count', 'rating');

// 取值,无对应评分时默认返回0
$fiveStars = $ratingStats[5] ?? 0;
$fourStars = $ratingStats[4] ?? 0;
$threeStars = $ratingStats[3] ?? 0;
$twoStars = $ratingStats[2] ?? 0;
$oneStar = $ratingStats[1] ?? 0;

// 也可以自行计算平均分,或者直接用方案2一步到位
$total = $fiveStars + $fourStars + $threeStars + $twoStars + $oneStar;
$overallRating = $total ? ($fiveStars * 5 + $fourStars * 4 + $threeStars * 3 + $twoStars * 2 + $oneStar) / $total : 0;

方案2:一步到位全量统计(推荐)

直接通过聚合函数一次性查出所有需要的字段,连平均分都由数据库直接计算完成,全程只执行1次SQL查询,不需要服务端做任何额外计算:

$stats = Review::query()
    ->selectRaw(
        'COUNT(CASE WHEN rating = 5 THEN 1 END) as five_stars,
        COUNT(CASE WHEN rating = 4 THEN 1 END) as four_stars,
        COUNT(CASE WHEN rating = 3 THEN 1 END) as three_stars,
        COUNT(CASE WHEN rating = 2 THEN 1 END) as two_stars,
        COUNT(CASE WHEN rating = 1 THEN 1 END) as one_star,
        AVG(rating) as overall_rating'
    )
    ->where('product_id', $data['product_id'])
    ->whereNotNull('published_at')
    ->first();

// 直接取值即可,无评论时平均分返回null可自行设置默认值
$fiveStars = $stats->five_stars;
$fourStars = $stats->four_stars;
$threeStars = $stats->three_stars;
$twoStars = $stats->two_stars;
$oneStar = $stats->one_star;
$overallRating = $stats->overall_rating ?? 0;

该方案兼容MySQL、PostgreSQL等绝大多数主流数据库,数据量越大相比你原写法的性能优势越明显,避免了全量拉取评论数据带来的内存占用和计算开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:48:04