题解 | 平均播放进度大于60%的视频类别

平均播放进度大于60%的视频类别

https://www.nowcoder.com/practice/c60242566ad94bc29959de0cdc6d95ef

一、题目思路

题目要求按 tag 统计视频的平均播放进度,并满足两点:

  • 无播放记录的标签不输出
  • 播放时长大于视频时长时,播放进度按 100% 计算

因此解题步骤很清晰:

  1. video_id 连接视频信息表和播放日志表
  2. TIMESTAMPDIFF 计算每条记录的播放时长
  3. LEAST 将单条记录播放进度封顶为 100%
  4. tag 分组求平均播放进度
  5. HAVING 筛选平均进度大于 60% 的标签
  6. CONCAT 拼接百分号输出结果

二、参考 SQL

SELECT v.tag,
       CONCAT(
           ROUND(
               AVG(
                   LEAST(TIMESTAMPDIFF(SECOND, u.start_time, u.end_time) / v.duration, 1)
               ) * 100,
               2
           ),
           '%'
       ) AS avg_play_progress
FROM tb_video_info v
JOIN tb_user_video_log u
ON v.video_id = u.video_id
GROUP BY v.tag
HAVING AVG(
           LEAST(TIMESTAMPDIFF(SECOND, u.start_time, u.end_time) / v.duration, 1)
       ) * 100 > 60
ORDER BY AVG(
            LEAST(TIMESTAMPDIFF(SECOND, u.start_time, u.end_time) / v.duration, 1)
         ) * 100 DESC;

三、知识点整理

1. WHEREHAVING 的辨析

区别

  • WHERE分组前筛选行
  • HAVING分组后筛选组

本题中的用法

本题要筛选的是:

AVG(...) * 100 > 60

这是对分组后的平均值进行筛选,属于聚合结果,因此必须用 HAVING,不能用 WHERE

通用模板

SELECT 分组字段, 聚合函数(...)
FROM 表
WHERE 行条件
GROUP BY 分组字段
HAVING 聚合条件

记忆

  • 筛单行:WHERE
  • 筛平均值、总和、计数等聚合结果:HAVING

2. CONCAT 函数

作用

用于拼接字符串

本题中的作用

把数值型平均播放进度拼接成带 % 的结果。

通用模板

CONCAT(字符串1, 字符串2, ...)

本题常见写法:

CONCAT(ROUND(某比例 * 100, 2), '%')

3. TIMESTAMPDIFF 函数

作用

计算两个时间之间的差值。

基本格式

TIMESTAMPDIFF(单位, 开始时间, 结束时间)

本题中的作用

计算每条播放记录的播放时长:

TIMESTAMPDIFF(SECOND, u.start_time, u.end_time)

表示播放秒数。

通用模板

TIMESTAMPDIFF(SECOND, start_col, end_col)

常用于停留时长、播放时长、处理耗时等题目。

4. LEFT JOINJOIN 的辨析

JOININNER JOIN

只保留两表中能匹配上的记录

LEFT JOIN

保留左表全部记录,右表匹配不到时补 NULL

本题为什么用 JOIN

题目要求没有播放记录的 tag 不输出,因此只保留有匹配播放日志的数据即可,用 JOIN 更合适。

通用模板

FROM A
JOIN B
ON A.id = B.id

FROM A
LEFT JOIN B
ON A.id = B.id

选择原则

  • 只统计有匹配数据的记录:JOIN
  • 需要保留左表全部记录:LEFT JOIN

5. LEAST 函数

作用

返回多个值中的最小值

本题中的作用

将单条播放进度封顶为 1,也就是 100%

LEAST(TIMESTAMPDIFF(SECOND, u.start_time, u.end_time) / v.duration, 1)

如果播放比例超过 1,就按 1 计算。

通用模板

LEAST(表达式, 上限值)

在“比例最多按 100% 算”的题目中很常见:

LEAST(实际值 / 总值, 1)

四、本题总结

这题本质上是一个连接 + 分组聚合 + 百分比格式化的问题:

  • JOIN 去掉无播放记录的标签
  • TIMESTAMPDIFF 算播放时长
  • LEAST 控制播放进度不超过 100%
  • AVG 求每个 tag 的平均播放进度
  • HAVING 筛选平均进度大于 60%
  • CONCAT 输出百分比格式

五、通用模板

SELECT 分组字段,
       CONCAT(ROUND(AVG(LEAST(实际值 / 总值, 1)) * 100, 2), '%') AS 结果
FROM 主表 A
JOIN 明细表 B
ON 连接条件
WHERE 行级条件
GROUP BY 分组字段
HAVING 聚合条件
ORDER BY AVG(LEAST(实际值 / 总值, 1)) DESC;

这类模板可以直接迁移到:

  • 播放进度
  • 完成率
  • 达成率
  • 使用率
  • 学习进度
全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务