SQL技术问题:如何按email聚合level总和并计算成绩百分比?
解决按用户Email计算个人Level总和的成绩百分比问题
我明白你的问题啦——你现在的查询用了CROSS JOIN,拿到的是整个history表的所有level总和,但你实际想要的是每个用户自己的level总和来计算成绩百分比,对吧?
问题出在哪?
你原来的查询里,CROSS JOIN (SELECT SUM(level) AS s FROM history) t会把rank表的每一行和一个包含全局level总和的单行表连接,所以所有用户的百分比计算都会用同一个全局总和,而不是自己的个人总和。这就是为什么你得不到预期结果的原因。
正确的解法步骤
我们需要先按email分组,计算每个用户在history表中的level总和,再把这个结果和rank表关联起来:
- 先写一个子查询,获取每个用户的
level总和:
SELECT email, SUM(`level`) AS total_level FROM `history` GROUP BY email
这个子查询会返回每个email对应的个人level总和(比如kemp的total_level就是4)。
- 把这个子查询和
rank表通过email关联,然后计算成绩百分比:
SELECT r.email, r.score, -- 计算百分比,用用户自己的level总和做分母 (r.score * 100) / h.total_level AS `Grade Percentage %` FROM `rank` r -- 用INNER JOIN确保只保留两个表都有记录的用户;如果要保留rank里所有用户,改用LEFT JOIN INNER JOIN (SELECT email, SUM(`level`) AS total_level FROM `history` GROUP BY email) h ON r.email = h.email -- 如果rank表中每个email只有一条score记录,GROUP BY r.email就足够;如果有多个score,根据需求调整分组 GROUP BY r.email, r.score;
额外优化:避免除以0的情况
如果某个用户在history表中没有任何记录,total_level会是NULL,这时计算会出错。可以用IFNULL处理这种情况:
(r.score * 100) / IFNULL(h.total_level, 1) AS `Grade Percentage %`
这里把NULL替换成1,避免除以0;你也可以根据实际需求换成其他默认值,或者用CASE语句过滤掉这类用户。
内容的提问来源于stack exchange,提问作者Rohan21
相关产品推荐
相关产品推荐

