用release time进行时间窗口筛选 + JOIN过滤无播放记录的视频

近一个月发布的视频中热度最高的top3视频

http://www.nowcoder.com/practice/0226c7b2541c41e59c3b8aec588b09ff

【2022.08.26 更新】

针对许多人的问题更新了代码~

SELECT
    video_id,
    ROUND((100 * finished_rate + 
           5 * like_cnt +
           3 * comment_cnt +
           2 * retweet_cnt) / (no_play_record_day_cnt + 1), 0) hot_index # 仔细查看指标定义,尤其是【新鲜度】
FROM (
        SELECT
            i.video_id,
            # 播放率:计算的是每个video_id在近一个月的播放率平均值。
            AVG(TIMESTAMPDIFF(second, start_time, end_time) >= duration) finished_rate, 
            SUM(if_like) like_cnt,
            COUNT(comment_id) comment_cnt, # COUNT会自动过滤空值。
            SUM(if_retweet) retweet_cnt,
            # 没有播放日的计算:从当天开始,到该视频的最后一个日期。
            # 【当天】:所有播放日期中的最大日期
            #【视频的最后播放日期】:按video_id聚合的维度下的最大日期,注意题目要求以【end-time】为准。
            DATEDIFF(DATE((SELECT MAX(end_time) FROM tb_user_video_log)), 
                     MAX(DATE(end_time))) no_play_record_day_cnt # 注意这里先要取出日期,再取最大值。
        FROM tb_video_info i
        JOIN tb_user_video_log USING(video_id)
        # 【近一个月内发布】的日期筛选
        #【近】:表示从当天开始,即所有播放日期中的最大日期
        # 【一个月内】:表示从当天开始,前推29天 --- 日期前推是【n-1】
        WHERE DATEDIFF(DATE((SELECT MAX(end_time) FROM tb_user_video_log)), DATE(release_time)) <= 29
        GROUP BY 1) t
ORDER BY 2 DESC 
LIMIT 3




【旧帖】

时间: 37ms 内存:6408KB

两个坑。

一、关于时间窗口的筛选

需求是最后播放日期往前推30天,如果用前面几题见到过的DATEDIFF法:

alt

后面那个不可以用end_time,而是应该用release_time, 因为存在视频发布当天并没有播放记录的情况。

举个例子:10.03往前推30天是09.04。我们要获取的统计时间区间是09.04-10.03。假设某个视频09.01发布,但是5天后才有第一次播放记录,那么这个视频最早的end_time是09.06,按照这个end_time,用DATEDIFF法来生成,得到的时间区间是09.06-10.03,明显不完整。个人感觉题目也是没有完全讲清楚。。

——————————————————————————————————

二、要过滤掉没有播放记录的视频

因为存在list里有,但log完全没有播放记录的video,比如2004。。所以在最初的子查询里面:

如果用LEFT JOIN,后面的WHERE要加上end_time IS NOT NULL

或者

直接用内连接JOIN过滤

——————————————————————————————————

代码如下:

SELECT
  video_id,
  ROUND((100 * finished_rate 
   + 5 * like_cnt 
   + 3 * comment_count 
   + 2 * retweet_cnt) / (unfinished_day_cnt + 1)) hot_index
FROM (
  SELECT
    i.video_id,
    SUM(TIMESTAMPDIFF(second, start_time, end_time) >= duration) / COUNT(*) finished_rate,
    SUM(if_like = 1) like_cnt,
    SUM(IF(comment_id IS NOT NULL, 1, 0)) comment_count,
    SUM(if_retweet = 1) retweet_cnt,
    DATEDIFF(DATE((SELECT MAX(end_time) FROM tb_user_video_log)), MAX(DATE(end_time))) unfinished_day_cnt
  FROM tb_video_info i
  JOIN tb_user_video_log USING(video_id)
  WHERE DATEDIFF(DATE((SELECT MAX(end_time) FROM tb_user_video_log)), DATE(release_time)) <= 29 
  GROUP BY 1
) t
ORDER BY 2 DESC LIMIT 3

全部评论
最近未播放天数定义完全不清晰,感觉大家都是根据结果倒退在理解。 在实际工作当中,如果这种指标定义不清晰,最终输出的数据只会造成更大的问题或者麻烦。
45 回复 分享
发布于 2021-12-17 16:23
未播放天数没看懂,为什么都是最近天数之间的差,DATEDIFF(DATE((SELECT MAX(end_time) FROM tb_user_video_log)), MAX(DATE(end_time))) unfinished_day_cnt
10 回复 分享
发布于 2021-12-12 20:52
我踩了一个很大的坑,我的代码逻辑没问题,但计算日期用成了timestampdiff,害惨了,怎么计算都不对,两个时间如果差一秒没满24小时,timestampdiff的结果都是0,超过24小时,小于48小时都是1
6 回复 分享
发布于 2023-03-17 17:39 上海
group by 1啥意思
3 回复 分享
发布于 2021-12-30 15:39
WHERE DATEDIFF((SELECT MAX(end_time) FROM tb_user_video_log),release_time) < 30 之所以这里要写release_time,是因为题目要求近一个月发布的视频,而不是近一个月有播放量的视频
1 回复 分享
发布于 2023-04-19 21:10 湖南
近一个月的视频中为啥要用max(end_time)和release_time相减呀
1 回复 分享
发布于 2022-06-21 11:23
这个思路最清晰 看这个友友们
1 回复 分享
发布于 2022-06-01 17:06
使用release_time是因为题目本来是就是求近一个月发布的视频,跟end_time没有关系,被误解了?
1 回复 分享
发布于 2022-05-09 16:25
找出近一个月发布为什么不是Datediff(Date((Select max(release_time) from tb_user_video_log)), date(release_time))<=29呢?答主写的是max(end_time)
1 回复 分享
发布于 2022-05-03 11:18
为什么SUM(TIMESTAMPDIFF(second, start_time, end_time) >= duration) / COUNT(*) finished_rate不加if呢
1 回复 分享
发布于 2022-01-11 15:16
请问一下,为什么DATE((SELECT MAX(end_time) FROM tb_user_video_log)),date后面必须要有两对括号,我之前只输了一对括号一直报错
1 回复 分享
发布于 2021-12-21 19:54
最内层的括号 (select max(end_time) from tb_user_video_log) 是一个子查询,它先执行并返回一个日期时间值所以再套一层date()去掉时间
点赞 回复 分享
发布于 03-31 22:53 上海
这段代码写得好漂亮学习了!
点赞 回复 分享
发布于 2024-05-03 11:14 浙江
select video_id,round((100*complete+5*il+3*ci+2*ir)/(clear+1),0) hot_index from (select t1.video_id, AVG(TIMESTAMPDIFF(second, start_time, end_time) >= duration) complete, datediff(date((select max(end_time) from tb_user_video_log)),max(date(end_time))) clear, sum(if_like) il, COUNT(comment_id) ci, sum(if_retweet) ir from tb_user_video_log t1 join tb_video_info t2 on t1.video_id=t2.video_id where datediff(date((select max(end_time) from tb_user_video_log)),date(end_time))<=29 group by t1.video_id ) t4 order by hot_index desc limit 3感觉已经写得一模一样了,可就是报错,最后会多筛出2002号视频
点赞 回复 分享
发布于 2024-04-07 15:42 台湾
WHERE DATEDIFF(DATE((SELECT MAX(end_time) FROM tb_user_video_log)), DATE(release_time)) <= 29请问这里,我直接用max(end_time),和DATEDIFF(DATE((SELECT MAX(end_time) FROM tb_user_video_log)),为什么会报错,明明结果都是2021-10-03 ,整个表里最近的日期明明是固定的呀,为什么非要用子集
点赞 回复 分享
发布于 2024-03-13 11:42 江苏
请问为什么是TIMESTAMPDIFF(second, start_time, end_time) >= duration,播放时长怎么能大于视频时长呢
点赞 回复 分享
发布于 2024-02-18 15:19 新疆
近三十天的筛选 ,按照题意是整表的最近播放的最大日期 ,向前推 29天 ; WHERE DATE(end_time) BETWEEN DATE_SUB( max_dt , INTERVAL 29 DAY ) AND max_dt # max_dt是整表最近播放的最大日期; 看大佬的意思 是每类视频的最近播放日期 向前推 到 发布日期 <= 29 那它们的统计周期 不就不统一了,即时间间隔在30 天内,但不一定在9/4~ 10/3 的统计周期内
点赞 回复 分享
发布于 2022-10-05 23:24 四川
为什么datediff里面要加date()函数,不可以DATEDIFF((SELECT MAX(end_time) FROM tb_user_video_log), MAX(end_time))
点赞 回复 分享
发布于 2022-04-04 11:09
大佬们,为什么我这样写结果不对阿?结果会少一个video_id为2002的情况: #error: where date(end_time) between date_sub((select max(date(end_time)) from tb_user_video_log),interval 1 month) and (select max(date(end_time)) from tb_user_video_log)
点赞 回复 分享
发布于 2022-03-31 08:39
请问下,datediff(时间单位,时间1,时间2)公式不是应该有个时间单位吗,为什么加上单位就不对了,一直报错,感谢!
点赞 回复 分享
发布于 2022-02-11 18:01

相关推荐

zygg:拼多多挂是不是过一两天就挂的呀
点赞 评论 收藏
分享
练习JAVA时长两年半:qps 30000
点赞 评论 收藏
分享
allin秋招的大菠萝很爱交友:后续,已拿offer ~查看图片
点赞 评论 收藏
分享
评论
75
15
分享

创作者周榜

更多
牛客网
牛客企业服务