垃圾帖移除率的每日平均
LeetCode 1132 · 先算日比率再求平均、LEFT JOIN 计数
面试怎么回答
先按日期算每天的移除率:被举报为 spam 的帖子 LEFT JOIN 移除表,COUNT(DISTINCT 移除帖子) / COUNT(DISTINCT 举报帖子);再对每日比率求 AVG 乘 100。我会主动点出「比率的平均」和「总量之比」口径不同,要和需求确认用哪个。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
行为表里有被举报为垃圾广告(spam)的帖子,移除表记录被移除的帖子。先算出每天「被举报为垃圾的帖子中最终被移除的比例」,再对这些每日比例求平均,以百分比形式保留两位小数。
表结构
- Actions:user_id、post_id、action_date、action、extra
- Removals:post_id(主键)、remove_date
思路
分两层:内层按举报日期分组,LEFT JOIN 移除表后,用「被移除的不同帖子数 / 被举报的不同帖子数」算出当天比例;外层对每日比例求 AVG 再乘 100。这是「比例的平均」,和「总移除数 / 总举报数」不是一回事。
参考解法
SELECT ROUND(AVG(proportion) * 100, 2) AS average_daily_percent
FROM (
SELECT actions.action_date, COUNT(DISTINCT removals.post_id)/COUNT(DISTINCT actions.post_id) AS proportion
FROM actions
LEFT JOIN removals
ON actions.post_id = removals.post_id
WHERE extra = 'spam'
GROUP BY actions.action_date
) a
易错点
- 直接用总数相除得到的是加权比例,题目要求的是每日比例的算术平均。
- 移除表要 LEFT JOIN,否则没被移除的帖子会从分母里消失,比例永远是 100%。