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

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

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

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

明确题意:

计算各类视频的平均播放进度,将进度大于60%的类别输出


问题分解:

  • 关联用户-视频互动记录和短视频信息表:JOIN tb_video_info USING(video_id);
  • 按视频类别分组:GROUP BY tag
  • 计算每个类别的平均播放进度:
    • 播放进度=播放时长÷视频时长*100%
    • 播放时长=TIMESTAMPDIFF(SECOND, start_time, end_time);特殊情况:播放时长大于视频时长时,播放进度为100%(加个IF判断)
    • 平均进度=AVG(每个进度)
    • 结果保留2位小数:ROUND(x, 2)
    • 百分比格式化:CONCAT(x, '%')
    • 计算公式:
    ROUND(AVG(
        IF(TIMESTAMPDIFF(SECOND, start_time, end_time) > duration, 1,
           TIMESTAMPDIFF(SECOND, start_time, end_time) / duration)
    ) * 100, 2) as avg_play_progress
  • 筛选播放进度>60%的视频类别:HAVING avg_play_progress > 60

细节问题:

  • 表头重命名:as
  • 按播放进度倒序排序:ORDER BY avg_play_progress DESC;

完整代码:

SELECT tag, CONCAT(avg_play_progress, "%") as avg_play_progress
FROM (
    SELECT tag, 
        ROUND(AVG(
            IF(TIMESTAMPDIFF(SECOND, start_time, end_time) > duration, 1,
               TIMESTAMPDIFF(SECOND, start_time, end_time) / duration)
        ) * 100, 2) as avg_play_progress
    FROM tb_user_video_log
    JOIN tb_video_info USING(video_id)
    GROUP BY tag
    HAVING avg_play_progress > 60
    ORDER BY avg_play_progress DESC
) as t_progress;
SQL大厂真题 文章被收录于专栏

大厂真题手把手教你怎么解~

全部评论
子查询的having子句是先于select子句执行,那此时avg_play_progress还没有的,麻烦楼主解释下,谢谢。
5 回复 分享
发布于 2022-03-08 10:20
为什么我的结果里包括旅游这个类别啊!??
2 回复 分享
发布于 2022-11-08 10:43 湖北
别看这个解析了 跑出来报错
1 回复 分享
发布于 2023-01-23 22:18 上海
好奇为什么IF(TIMESTAMPDIFF(SECOND, start_time, end_time) > duration结果中要>duration播放时长,如果不大于播放时长,大于0不就可以了吗
1 回复 分享
发布于 2022-11-11 21:23 广东
IF(TIMESTAMPDIFF(SECOND, start_time, end_time) > duration, 1, TIMESTAMPDIFF(SECOND, start_time, end_time) / duration) 请教楼主 IF函数中 TIMESTAMPDIFF(SECOND, start_time, end_time) > duration 这个字段中并没有真值 那么这个真值1的作用是什么 有点搞不懂 谢谢
1 回复 分享
发布于 2022-06-07 03:34
想问一下 将TIMESTAMPDIFF换成两个日期相减就不对了 这是为什么呢
1 回复 分享
发布于 2022-04-09 12:53
为什么left join不可以,必须用join呢
1 回复 分享
发布于 2022-03-12 22:37
想问问为什么我写出来没有90%这个结果呢
点赞 回复 分享
发布于 2024-01-26 14:31 香港
SELECT tag, concat(ROUND(AVG( IF(TIMESTAMPDIFF(SECOND, start_time, end_time) > duration, 1, TIMESTAMPDIFF(SECOND, start_time, end_time) / duration) ) * 100, 2),"%" )as avg_play_progress FROM tb_user_video_log JOIN tb_video_info USING(video_id) GROUP BY tag HAVING avg_play_progress > 60 ORDER BY avg_play_progress DESC 这样也可以
点赞 回复 分享
发布于 2023-09-22 13:17 广东
select A.tag,concat(truncate(A.u*100,2),'%') from (select tag,round((avg(if((timestampdiff(second,a.start_time,a.end_time))/duration>1,1,(timestampdiff(second,a.start_time,a.end_time)/duration)))),4) as u from tb_user_video_log a left join tb_video_info b on a.video_id=b.video_id group by tag having u>0.6 order by u desc)as A
点赞 回复 分享
发布于 2023-02-08 13:26 重庆
你应该是直接剪的,没用TIMESTAMPDIFF吧?直接减是100进制的
点赞 回复 分享
发布于 2022-11-10 16:27 安徽
为什么这么写会报错? select tag, round(avg( IF(TIMESTAMPDIFF(SECOND, start_time, end_time) > duration, 100%, TIMESTAMPDIFF(SECOND, start_time, end_time) / duration*100% ) ) ,2) as avg_play_progress from tb_user_video_log as a inner join tb_video_info as b on a.video_id=b.video_id group by tag HAVING avg_play_progress > 60% order by avg_play_progress DESC;
点赞 回复 分享
发布于 2022-09-21 10:38 广东
请问第三行为什么不能select*呢,select*会报错"Duplicate column name 'id'"重复列名,这个指的是什么呢
点赞 回复 分享
发布于 2022-08-09 11:12
请问为什么可以直接having avg_play_progress>60呢,不是加了%了吗
点赞 回复 分享
发布于 2022-06-07 15:49
没有报错,可直接使用
点赞 回复 分享
发布于 2022-05-30 23:35
请问为什么把round后面的一串代码和%直接写进concat就会报错呢
点赞 回复 分享
发布于 2022-05-06 00:53
这个答案很棒了,和我提交六七次错误版本迭代出来的正确sql差不多 select tag, concat(progress_rate, '%') avg_play_progress from ( select tag, round(avg(if(timestampdiff(SECOND, start_time, end_time)>duration,duration,timestampdiff(SECOND, start_time, end_time))/duration)*100, 2) progress_rate from tb_user_video_log a left join tb_video_info b on a.video_id=b.video_id group by b.tag having progress_rate>60 order by progress_rate desc) c;
点赞 回复 分享
发布于 2022-03-22 22:37
请问为什么第二行 第八行有两个from呢
点赞 回复 分享
发布于 2022-03-16 20:21

相关推荐

每晚夜里独自颤抖:这个在牛客不是老熟人了吗
点赞 评论 收藏
分享
评论
149
18
分享

创作者周榜

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