SQL COUNT统计异常求助:按产品分类统计评论数结果不符
解决评论统计数异常的问题
嘿,我一眼就看出你的SQL语句里的问题啦——统计数从6变成24,大概率是笛卡尔积+子查询未关联主表导致的重复计数,咱们一步步来修正:
问题根源分析
你原来的子查询犯了两个关键错误:
- 子查询里硬编码了
C.CategoryName = 'T-Models',而且没有和主查询的分类做关联,导致不管主查询遍历到哪个分类,子查询都返回同一个固定的评论数; - 子查询里用了多层
FULL JOIN,这会把所有不匹配的行都拉进来,加上主查询里ProductRankingHistory和Category的连接,如果某个分类在ProductRankingHistory里有4条记录(24÷6=4),就会把6重复计算4次,最终得到24。
另外,FULL JOIN在这里完全没必要,评论是关联产品、产品关联分类,用INNER JOIN或者LEFT JOIN就足够了。
修正方案1:关联子查询写法
这种写法逻辑清晰,适合需要按主表维度统计的场景:
SELECT PRH.PRHYear AS 'Year', C.CategoryName AS 'Category', -- 子查询关联主查询的CategoryID,只统计当前分类的评论 (SELECT COUNT(DISTINCT R.ReviewID) FROM Review R INNER JOIN Product P ON R.ProductID = P.ProductID INNER JOIN Category C_sub ON P.CategoryID = C_sub.CategoryID WHERE C_sub.CategoryID = C.CategoryID) AS 'Reviews' FROM ProductRankingHistory PRH INNER JOIN Category C ON PRH.PRHCategory = C.CategoryID -- 按年份和分类分组,避免同一维度重复行 GROUP BY PRH.PRHYear, C.CategoryName -- 按年份+评论数排序 ORDER BY PRH.PRHYear, Reviews DESC;
这里用COUNT(DISTINCT R.ReviewID)是为了防止因为产品和历史表的关联导致评论被重复统计,如果你的ReviewID是唯一主键,也可以直接用COUNT(R.ReviewID)。
修正方案2:JOIN+分组聚合(更高效)
这种写法用一次连接完成统计,性能比子查询更好:
SELECT PRH.PRHYear AS 'Year', C.CategoryName AS 'Category', COUNT(DISTINCT R.ReviewID) AS 'Reviews' FROM ProductRankingHistory PRH INNER JOIN Category C ON PRH.PRHCategory = C.CategoryID -- LEFT JOIN保留没有评论的分类,不需要的话换成INNER JOIN LEFT JOIN Product P ON C.CategoryID = P.CategoryID LEFT JOIN Review R ON P.ProductID = R.ProductID GROUP BY PRH.PRHYear, C.CategoryName ORDER BY PRH.PRHYear, Reviews DESC;
额外提示
- 如果你的
ProductRankingHistory里同一年同一分类有多条重复记录,记得要么用GROUP BY去重,要么在主查询里加DISTINCT; - 永远避免在子查询里硬编码固定值,一定要和主表做关联,不然统计结果会完全偏离预期。
内容的提问来源于stack exchange,提问作者VallyMan
相关产品推荐
相关产品推荐

