SQL新手求助:编写查询语句筛选Top5高分高热度商品
嘿,作为SQL新手能想到做商品排名功能已经很赞啦!我来帮你一步步拆解需求,写出完全符合要求的SQL语句~
首先明确你的核心需求:先按评分从高到低排序,评分相同的情况下,选评分人数最多的,最终取前5个商品ID。咱们一步步来:
第一步:聚合每个商品的评分数据
首先我们需要从Review表中统计每个商品的平均评分和评分人数,这一步用GROUP BY来实现:
SELECT r.product_id, AVG(r.score) AS avg_score, -- 计算平均评分 COUNT(r.user_id) AS review_count -- 统计评分人数 FROM Review r GROUP BY r.product_id
小提醒:如果担心同一个用户对同一个商品重复评分(虽然题目没提,但实际场景可能存在),可以把
COUNT(r.user_id)改成COUNT(DISTINCT r.user_id),这样能保证每个用户只被统计一次。
第二步:按需求排序并取Top5
接下来我们按照「平均评分降序 → 评分人数降序」的规则排序,然后只取前5个结果:
SELECT r.product_id, AVG(r.score) AS avg_score, COUNT(r.user_id) AS review_count FROM Review r GROUP BY r.product_id ORDER BY avg_score DESC, review_count DESC -- 先比评分,再比人数 LIMIT 5; -- 取前5个
不同数据库的小差异
上面的语句适用于MySQL、PostgreSQL这类数据库,如果用的是其他数据库,调整一下取Top的方式就行:
- SQL Server:把
LIMIT 5换成TOP 5,放在SELECT后面:SELECT TOP 5 r.product_id, AVG(r.score) AS avg_score, COUNT(r.user_id) AS review_count FROM Review r GROUP BY r.product_id ORDER BY avg_score DESC, review_count DESC; - Oracle:需要用子查询加
ROWNUM过滤:SELECT product_id, avg_score, review_count FROM ( SELECT r.product_id, AVG(r.score) AS avg_score, COUNT(r.user_id) AS review_count FROM Review r GROUP BY r.product_id ORDER BY avg_score DESC, review_count DESC ) ranked_products WHERE ROWNUM <= 5;
可选:关联商品表获取名称
如果需要同时显示商品名称,可以关联Product表:
SELECT r.product_id, p.product_name, AVG(r.score) AS avg_score, COUNT(r.user_id) AS review_count FROM Review r JOIN Product p ON r.product_id = p.product_id GROUP BY r.product_id, p.product_name ORDER BY avg_score DESC, review_count DESC LIMIT 5;
新手注意事项
- 确保
Review.product_id和Product.product_id是关联的外键,这样JOIN的时候不会出现数据不匹配的问题; - 如果有商品没有任何用户评分,会被自动排除(因为我们是基于
Review表聚合的),这符合你「评分最高」的需求,毕竟没评分的商品没有评分数据; - 如果想让平均评分显示更友好(比如保留两位小数),可以用
ROUND(AVG(r.score), 2) AS avg_score。
内容的提问来源于stack exchange,提问作者Phuong Nguyen
相关产品推荐
相关产品推荐

