Data Engineer / Data Scientist · DE / SQL

Meta 观看时长SQL:Session粒度、用户与类型

汇总用户某日各类型观看时长,区分累积播放点、时长增量与多标签连接。

题目重点:汇总用户某日各类型观看时长,区分累积播放点、时长增量与多标签连接。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练watch一行一个去重播放session,watched_seconds为有效时长非累计heartbeat值;video一行一视频/单genre,day按统一业务时区派生。

解题路线

  1. 筛选指定day,join video维表,按user_id/genre SUM seconds。秒与分钟输出转换单独明确,不能将session数当watch time。
  2. 如果输入heartbeat是累计播放时长,必须先按session/seq去重并转增量或取有效最终值;直接sum所有累计点严重翻倍。暂停/seek与同视频多session是否计入由口径定。
  3. video多genre时桥表一对多会复制watch时长。选择主genre、全归因或加权归因需定义,否则各genre之和超过全体观看时间。
  4. 缺video维度时inner join会漏事件;数据质量监测丢失量,是否归Unknown由合同定。示例维表完整,不把缺失当0时长掩盖。

手动走一遍

用户u看电影a两次session,秒数10和20,合30;若同session三条累计10/20/30,真实末累计30而不是60。video只有一个genre时类型汇总和可对账总时长。

SQL 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

-- Training: watch(event_id PK,user_id,video_id,watch_date,watched_seconds)
-- Valid deduped sessions, nonnegative seconds, date derived by agreed business TZ.
-- video(video_id PK,genre). One genre per video in this training model.
SELECT w.user_id, v.genre, SUM(w.watched_seconds) AS total_watch_seconds
FROM watch w JOIN video v ON v.video_id=w.video_id
WHERE w.watch_date=:day
GROUP BY w.user_id, v.genre
ORDER BY w.user_id, v.genre;

复杂度

按日期分区扫描Wday事实与video join,hash聚合状态按user×genre;事实去重/heartbeat转换增加上游成本。索引不能让读取全日全部事件自动O(1)。

易错点与追问

容易失分的边界

  • 累计heartbeat直接相加造成系统性高估。
  • 多标签join未说明归因,重复分配同一时长。

继续深挖

  • 跨午夜session按开始日还是按实际观看片段分配?先定时区与分割政策。
  • 离线事件晚到怎样修正已发布日指标?按版本重算而非重复increment。
✓已复制微信号!