MySQL - 从基本评论中检索评分和评论摘要的最佳方式 table 例如google

MySQL - best way to retrieve rating and reviews summary from a basic review table e.g. google

我已经构建了一个基本的 table 来存储我的评论和评分,并想检索上述插件的详细信息。

review_id | company_id | user_id | rating | review
1           1            1         3        Great
2           1            2         5        Thank you
3           1            3         5        Great
4           1            4         4        Thank you
5           1            5         1        Great
6           1            6         2        Thank you
7           2            5         1        Great
8           2            6         2        Thank you

SQL 获取摘要

SELECT company_id as cid, ROUND(AVG(rating)) AS rate, COUNT(*) AS review_count, 
(SELECT COUNT(*) FROM `reviews` WHERE `rating` = 5 AND `company_id` = cid) AS rating_5,
((SELECT COUNT(*) FROM `reviews` WHERE `rating` = 5 AND `company_id` = cid) / COUNT(*) * 100) AS rating_5_avg,
(SELECT COUNT(*) FROM `reviews` WHERE `rating` = 4 AND `company_id` = cid) AS rating_4,
((SELECT COUNT(*) FROM `reviews` WHERE `rating` = 4 AND `company_id` = cid) / COUNT(*) * 100) AS rating_4_avg,
(SELECT COUNT(*) FROM `reviews` WHERE `rating` = 3 AND `company_id` = cid) AS rating_3,
((SELECT COUNT(*) FROM `reviews` WHERE `rating` = 3 AND `company_id` = cid) / COUNT(*) * 100) AS rating_3_avg,
(SELECT COUNT(*) FROM `reviews` WHERE `rating` = 2 AND `company_id` = cid) AS rating_2,
((SELECT COUNT(*) FROM `reviews` WHERE `rating` = 2 AND `company_id` = cid) / COUNT(*) * 100) AS rating_2_avg,
(SELECT COUNT(*) FROM `reviews` WHERE `rating` = 1 AND `company_id` = cid) AS rating_1,
((SELECT COUNT(*) FROM `reviews` WHERE `rating` = 1 AND `company_id` = cid) / COUNT(*) * 100) AS rating_1_avg

FROM `reviews` GROUP BY company_id

结果:

我确信有更好的方法(优化)来做到这一点,但我猜不到所以我再次需要帮助。

问:如何优化更多?

您可以使用条件聚合完成此任务:

SELECT company_id as cid, 
       ROUND(AVG(rating)) AS rate, 
       COUNT(*) AS review_count,
       COUNT(CASE WHEN `rating` = 5 THEN 1 END) AS rating_5,
       COUNT(CASE WHEN `rating` = 5 THEN 1 END) / (COUNT(*) * 100) AS rating_5_avg,
        ... etc 
FROM `reviews` 
GROUP BY company_id

使用包含 CASE 表达式的聚合:

COUNT(CASE WHEN `rating` = 5 THEN 1 END)

您可以根据 rating 字段的值获得 company_id 记录子集的计数。