订阅更新

垃圾帖移除率的每日平均

SQL 实战 123 题 · 第 63 题 中等 约 2 分钟读完

LeetCode 1132 · 先算日比率再求平均、LEFT JOIN 计数

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

先按日期算每天的移除率:被举报为 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%。
刷题进度保存在当前浏览器