首页 > 试题广场 >

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

[编程题]近一个月发布的视频中热度最高的top3视频
  • 热度指数:106789 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

现有用户-视频互动表tb_user_video_log

id uid video_id start_time end_time if_follow if_like if_retweet comment_id
1 101 2001 2021-09-24 10:00:00 2021-09-24 10:00:30
1 1 1 NULL
2 101
2001 2021-10-01 10:00:00
2021-10-01 10:00:31
1 1 0 NULL
3 102
2001 2021-10-01 10:00:00
2021-10-01 10:00:35
0 0 1 NULL
4 103
2001 2021-10-03 11:00:50
2021-10-03 10:00:35
1 1 0 1732526
5 106
2002 2021-10-02 11:00:05
2021-10-02 11:01:04
2 0 1 NULL
6 107 2002 2021-10-02 10:59:05
2021-10-02 11:00:06
1 0 0 NULL
7
108 2002 2021-10-02 10:59:05
2021-10-02 11:00:05
1 1 1 NULL
8
109 2002 2021-10-03 10:59:05
2021-10-03 11:00:01
0 1 0 NULL
9 105
2002 2021-09-25 11:00:00
2021-09-25 11:00:30
1 0 1 NULL
10 101
2003
2021-09-26 11:00:00
2021-09-26 11:00:30
1 0 0 NULL
11 101 2003
2021-09-30 11:00:00
2021-09-30 11:00:30
1 1 0 NULL
uid-用户ID, video_id-视频ID, start_time-开始观看时间, end_time-结束观看时间, if_follow-是否关注, if_like-是否点赞, if_retweet-是否转发, comment_id-评论ID)


短视频信息表tb_video_info


id video_id author tag duration release_time
1 2001 901 旅游 30 2021-09-05 07:00:00
2 2002
901
旅游 60 2021-09-05 07:00:00
3 2003
902
影视 90 2021-09-05 07:00:00
4 2004 902 影视 90 2021-09-05 08:00:00


(video_id-视频ID, author-创作者ID, tag-类别标签, duration-视频时长, release_time-发布时间)


问题:找出近一个月发布的视频中热度最高的top3视频。

  • 热度=(a*视频完播率+b*点赞数+c*评论数+d*转发数)*新鲜度;
  • 新鲜度=1/(最近无播放天数+1);
  • 当前配置的参数a,b,c,d分别为100、5、3、2。
  • 最近播放日期以end_time-结束观看时间为准,假设为T,则最近一个月按[T-29, T]闭区间统计。
  • 结果中热度保留为整数,并按热度降序排序。

输出示例
示例数据的输出结果如下

video_id hot_index
2001 122
2002 56
2003 1

解释:
最近播放日期为2021-10-03,记作当天日期;近一个月(2021-09-04及之后)发布的视频有2001、2002、2003、2004,不过2004暂时还没有播放记录;
视频2001完播率1.0(被播放次数4次,完成播放4次),被点赞3次,评论1次,转发2次,最近无播放天数为0,因此热度为:(100*1.0+5*3+3*1+2*2)/(0+1)=122
同理,视频2003完播率0,被点赞数1,评论和转发均为0,最近无播放天数为3,因此热度为:(100*0+5*1+3*0+2*0)/(3+1)=1(1.2保留为整数)。
示例1

输入

DROP TABLE IF EXISTS tb_user_video_log, tb_video_info;
CREATE TABLE tb_user_video_log (
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    uid INT NOT NULL COMMENT '用户ID',
    video_id INT NOT NULL COMMENT '视频ID',
    start_time datetime COMMENT '开始观看时间',
    end_time datetime COMMENT '结束观看时间',
    if_follow TINYINT COMMENT '是否关注',
    if_like TINYINT COMMENT '是否点赞',
    if_retweet TINYINT COMMENT '是否转发',
    comment_id INT COMMENT '评论ID'
) CHARACTER SET utf8 COLLATE utf8_bin;

CREATE TABLE tb_video_info (
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    video_id INT UNIQUE NOT NULL COMMENT '视频ID',
    author INT NOT NULL COMMENT '创作者ID',
    tag VARCHAR(16) NOT NULL COMMENT '类别标签',
    duration INT NOT NULL COMMENT '视频时长(秒数)',
    release_time datetime NOT NULL COMMENT '发布时间'
)CHARACTER SET utf8 COLLATE utf8_bin;

INSERT INTO tb_user_video_log(uid, video_id, start_time, end_time, if_follow, if_like, if_retweet, comment_id) VALUES
   (101, 2001, '2021-09-24 10:00:00', '2021-09-24 10:00:30', 1, 1, 1, null)
  ,(101, 2001, '2021-10-01 10:00:00', '2021-10-01 10:00:31', 1, 1, 0, null)
  ,(102, 2001, '2021-10-01 10:00:00', '2021-10-01 10:00:35', 0, 0, 1, null)
  ,(103, 2001, '2021-10-03 11:00:50', '2021-10-03 11:01:35', 1, 1, 0, 1732526)
  ,(106, 2002, '2021-10-02 10:59:05', '2021-10-02 11:00:04', 2, 0, 1, null)
  ,(107, 2002, '2021-10-02 10:59:05', '2021-10-02 11:00:06', 1, 0, 0, null)
  ,(108, 2002, '2021-10-02 10:59:05', '2021-10-02 11:00:05', 1, 1, 1, null)
  ,(109, 2002, '2021-10-03 10:59:05', '2021-10-03 11:00:01', 0, 1, 0, null)
  ,(105, 2002, '2021-09-25 11:00:00', '2021-09-25 11:00:30', 1, 0, 1, null)
  ,(101, 2003, '2021-09-26 11:00:00', '2021-09-26 11:00:30', 1, 0, 0, null)
  ,(101, 2003, '2021-09-30 11:00:00', '2021-09-30 11:00:30', 1, 1, 0, null);

INSERT INTO tb_video_info(video_id, author, tag, duration, release_time) VALUES
   (2001, 901, '旅游', 30, '2021-09-05 7:00:00')
  ,(2002, 901, '旅游', 60, '2021-09-05 7:00:00')
  ,(2003, 902, '影视', 90, '2021-09-05 7:00:00')
  ,(2004, 902, '影视', 90, '2021-09-05 8:00:00');

输出

2001|122
2002|56
2003|1
SELECT t0.video_id
     , ROUND((100 * AVG(IF(TIMESTAMPDIFF(SECOND, start_time, end_time) >= t1.duration, 1, 0)) +
              5 * SUM(t0.if_like) +
              3 * COUNT(t0.comment_id) +
              2 * SUM(t0.if_retweet)) /
             (DATEDIFF((SELECT MAX(end_time) FROM tb_user_video_log), MAX(end_time)) + 1), 0) AS hot_index
FROM tb_user_video_log t0
         LEFT JOIN tb_video_info t1
                   ON t0.video_id = t1.video_id
WHERE DATEDIFF((SELECT MAX(end_time) FROM tb_user_video_log), t1.release_time) <= 29
GROUP BY t0.video_id
ORDER BY hot_index DESC
LIMIT 3;

发表于 2024-04-13 21:09:49 回复(0)
select  video_id,
        round((100*a+b*5+c*3+d*2)/( datediff( date((select max(end_time) from tb_user_video_log)), date(tm)) + 1)) as hot_index
from
(
    select  t1.video_id,
            # 完播率
            avg(if(timestampdiff(second,start_time,end_time)>=duration,1,0))
                as a,
            sum(if_like) as b,
            count(comment_id) as c,
            sum(if_retweet) as d,
            # 视频最新播放时间
            max(end_time) as tm
    from tb_user_video_log t1
    join tb_video_info t2
    on t1.video_id=t2.video_id
    and datediff( date((select max(end_time) from tb_user_video_log)),
            date(release_time)) < 30
    group by t1.video_id
) tmp
order by hot_index desc
limit 3




发表于 2024-04-06 22:07:32 回复(0)
所以这道题的重点是区别timestampdiff和datediff?牛牛无语

select
    video_id,
    round((100*complete_play_rate + 5*total_likes+3*total_comments+2*total_retweets)*new_score) hot_index
from(
    select
        tv.video_id,
        tv.release_time,
        tu.latest_time,
        avg(case when timestampdiff(second,tu.start_time,tu.end_time) >= tv.duration then 1
                 else 0 end) complete_play_rate,
        sum(tu.if_like) total_likes,
        count(tu.comment_id) total_comments,
        sum(tu.if_retweet) total_retweets,
        1/(datediff(tu.latest_time,max(tu.end_time))+1) new_score
    from
        tb_video_info tv left join 
        (select 
            video_id,
            start_time,
            end_time,
            if_follow,
            if_like,
            if_retweet,
            comment_id,
            max(end_time) over() latest_time
        from tb_user_video_log ) tu
        on tv.video_id = tu.video_id 
    group by tv.video_id,tv.release_time,tu.latest_time
    ) t1
where datediff(latest_time,release_time)<=29
order by hot_index desc
limit 3


发表于 2024-04-03 13:21:00 回复(0)
with 
t as #信息总表
(
select 
    video_id
    , if_like
    , if_retweet
    , case when timestampdiff(second, start_time, end_time)>=duration then 1 else 0 end as if_finish
    , comment_id
from tb_user_video_log  inner join tb_video_info using(video_id)
where datediff((select max(end_time) from tb_user_video_log), end_time)<=29
    and datediff((select max(end_time) from tb_user_video_log), release_time)<=29
),
t1 as #分组统计完播率、点赞数、评论数
(
select 
    video_id
    , avg(if_finish) as fsh_r
    , sum(if_like) as lk_n
    , count(comment_id) as cm_n
    , sum(if_retweet) as rt_n
    
from t
group by video_id
),
t2 as #最近无播放天数
(
select 
    video_id
    , datediff((select max(end_time) from tb_user_video_log), max(end_time)) as nv
from tb_user_video_log  inner join tb_video_info using(video_id)
group by video_id
)

select 
    video_id
    , round((100*fsh_r + 5*lk_n + 3*cm_n + 2*rt_n) / (nv+1)) as hot_index
from t1 join t2 using(video_id)
order by hot_index desc
limit 3
;
为什么差一个啊啊啊啊啊啊

发表于 2024-02-14 13:44:04 回复(1)
SELECT 
T1.video_id,
ROUND((100*T1.完播率+5*T1.点赞数+3*T1.评论数+2*T1.转发数)/(datediff(T2.最大视频时间,T1.单视频最近时间)+1),0) AS hot_index
FROM
    (
        -- 取出进一个月发布的视频的:点赞数,评论数,转发数,完播率,单视频最近播放时间
        select 
        t1.video_id,
        sum(t1.if_like) as 点赞数,
        count(t1.comment_id) as 评论数,
        sum(t1.if_retweet) as 转发数,
        max(date(t1.end_time)) 单视频最近时间,
        avg(if(TIMESTAMPDIFF(SECOND,t1.start_time,t1.end_time)>=t2.duration,1,0)) as 完播率
        from tb_user_video_log as t1
        left join tb_video_info as t2
        on t1.video_id = t2.video_id
        where TIMESTAMPDIFF(day,t1.end_time,(select max(release_time) from tb_video_info)) <= 29
        group by t1.video_id
    ) T1

    left join
    (   -- 匹配全部视频的最近播放时间
        select
        video_id,
        date(end_time) as 单视频最近时间,
        max(date(end_time)) over() as 最大视频时间
        from tb_user_video_log 
    ) T2
    on T1.video_id = T2.video_id and T1.单视频最近时间= T2.单视频最近时间
ORDER BY hot_index DESC limit 3
请各位大佬给看看,到底是哪里又问题呢?
发表于 2023-12-21 11:57:11 回复(0)
我感觉我的几乎一模一样,有没有大佬能帮忙看看为什么第一个测试用例2003会输出21?(答案是11)
select video_id,round((100*wbl+5*dzs+3*pls+2*zfs)/(1+gapdays),0) as hot_index
from(
    select a.video_id,avg(if(timediff(end_time,start_time)>=duration,1,0)) wbl,
    sum(if_like) dzs,count(comment_id) pls,sum(if_retweet) zfs,
    datediff((select max(date(end_time)) from tb_user_video_log),max(date(end_time))) gapdays
    from tb_user_video_log a,tb_video_info b
    where a.video_id=b.video_id
    and datediff((select max(date(end_time)) from tb_user_video_log),date(release_time))<30
    and end_time is not null
    group by a.video_id
)tmp
order by hot_index desc
limit 3

发表于 2023-11-30 20:55:24 回复(0)


#要用timestampdiff才得到正确答案,最近无播放天数指的是该视频最后播放时间距离所有视频最后播放时间的距离
select w.video_id,
round((100*finishrate+5*likenum+3*commentnum+2*renum)/(noplay+1),0) hot_index
from
(select u.video_id,
    avg(if(timestampdiff(second, u.start_time, u.end_time) >= v.duration, 1, 0)) as finishrate,
    sum(u.if_like) as likenum,
    count(u.comment_id) as commentnum,
    sum(u.if_retweet) as renum,
    datediff((select max(DATE(end_time)) from tb_user_video_log), max(date(u.end_time))) as noplay
from tb_user_video_log u
left join tb_video_info  v
on u.video_id=v.video_id
where datediff((select max(date(end_time)) from tb_user_video_log), date(v.release_time))<=29
group by v.video_id) w
order by hot_index desc
limit 3;


发表于 2023-10-29 22:20:33 回复(0)

select
t1.video_id,
round(
(
  (sum(if(TimeStampDiff(second,start_time,end_time) >= duration,1,0))/count(*)) * 100
+ sum(if_like) * 5
+ count(comment_id) * 3
+ sum(if_retweet) * 2
)
/
(TimeStampDiff(day,max(date(end_time)), (select max(date(end_time)) from tb_user_video_log)) + 1 ),0) as hot_index
from tb_user_video_log t1
left join tb_video_info t2 on t1.video_id = t2.video_id
where date(release_time) between  DATE_SUB((select max(date(end_time)) from tb_user_video_log), INTERVAL 29 DAY) and (select max(date(end_time)) from tb_user_video_log)
group by video_id
order by hot_index desc
limit 3
发表于 2023-10-17 17:41:14 回复(0)
为什么这样不对啊
select 
    video_id,
    round((100*com_rate+5*like_cnt+3*comment_cnt+2*retweet_cnt)/fresh_index,0) hot_index
from (
    select 
        t1.video_id,
        sum(if(timestampdiff(second,t1.start_time,t1.end_time) >= t2.duration,1,0))/  count(t1.video_id) com_rate,
        sum(if_like) like_cnt,
        count(comment_id) comment_cnt,
        sum(if_retweet) retweet_cnt,
        if(count(end_time)=0,timestampdiff(day,release_time,(select max(end_time) from tb_user_video_log)),timestampdiff(day,max(end_time),(select max(end_time) from tb_user_video_log)))+1 fresh_index
    from tb_user_video_log t1
        left join tb_video_info t2
        on t1.video_id = t2.video_id
    where timestampdiff(day,t2.release_time,(select max(end_time) from tb_user_video_log)) <= 29
    group by t1.video_id) table1
order by hot_index desc
limit 0,3

发表于 2023-10-13 19:48:46 回复(0)
with tt as(
    select 
        t1.video_id,
        sum(t1.if_like) as count_like,
        count(t1.comment_id) as count_comment_id,
        sum(t1.if_retweet) as count_retweet	,
        count(if(timestampdiff(second,t1.start_time,t1.end_time)>=t2.duration,1,null))/count(t1.start_time) as wanbo,
        datediff((select max(end_time) from tb_user_video_log),max(end_time)) as no_day
    from tb_user_video_log t1
        left join tb_video_info t2
        using(video_id)
    where datediff((select  max(end_time) from tb_user_video_log) ,end_time) <=29
        and t2.release_time>date_sub((select max(end_time) from tb_user_video_log) ,interval 29 day)
    group by t1.video_id)

select 
    tt.video_id,
   round((tt.wanbo*100+tt.count_like*5+tt.count_comment_id*3+count_retweet*2)*(1/(no_day+1)),0) as hot_index
from tt
order by hot_index desc
limit 3;
不知道这种题一般给多久时间作答,理解起来挺费劲的,弯弯绕绕的,容易写错,但是其实没那么难
发表于 2023-10-07 20:22:03 回复(0)
1.当天日期
2.近1个月播放记录
3.近1个月发布的视频
4.按视频分组计算热度,保留0位小数
5.排序、取前3
select t3.video_id,
round(
    (
    100*sum(if(timestampdiff(second,t1.start_time,t1.end_time)>=t3.duration,1,0))/count(t1.id)
    +5*sum(t1.if_like)
    +3*count(t1.comment_id)
    +2*sum(t1.if_retweet)
    )/
(datediff(t2.curr_date,max(t1.end_time))+1),0
) 
as hot_index
from tb_user_video_log as t1
#当天日期
join (select max(end_time) as curr_date from tb_user_video_log) as t2
#筛选近一个月的播放记录
on datediff(t1.end_time, t2.curr_date)<=0 and datediff(t1.end_time, t2.curr_date)>=-29
join tb_video_info as t3 
#限定发布日期:近一个月发布
on t1.video_id=t3.video_id
and datediff(t3.release_time, t2.curr_date)<=0 and datediff(t3.release_time, t2.curr_date)>=-29
#分组统计:因为datediff函数中用到了t2.curr_date值,所以该字段必须加入分组字段中
group by t3.video_id,t2.curr_date
order by hot_index desc
limit 3



发表于 2023-09-20 09:59:01 回复(0)
select t0.video_id,
round((100*complete_rate+5*likes+3*comments+2*retweets)*(1/(no_play+1)),0) as hot_index
from
(select t1.video_id,
count(if(duration - (select
case
when minute(end_time) = minute(start_time) then second(end_time) - second(start_time)
else second(end_time)+60-second(start_time)
end)<=0,1,null)) / count(t1.video_id) as complete_rate,
sum(if_like) as likes,
count(comment_id) as comments,
sum(if_retweet) as retweets,
datediff((select max(end_time) from tb_user_video_log), max(end_time)) as no_play
from tb_user_video_log as t1
join tb_video_info as t2
on t1.video_id = t2.video_id
where datediff((select max(end_time) from tb_user_video_log), t2.release_time) <= 29
group by t1.video_id) as t0
order by hot_index desc
limit 3

发表于 2023-08-23 18:01:50 回复(0)
# 问题:找出近一个月发布的视频中热度最高的top3视频。

# 注:
# 热度=(a*视频完播率+b*点赞数+c*评论数+d*转发数)*新鲜度;
# 新鲜度=1/(最近无播放天数+1);
# 当前配置的参数a,b,c,d分别为100、5、3、2。
# 最近播放日期以end_time-结束观看时间为准,假设为T,则最近一个月按[T-29, T]闭区间统计。
# 结果中热度保留为整数,并按热度降序排序。
-- 注意:timestampdiff 与datediff 正好相反,参数大小方向;
-- 注意:最近90天,使用发布日期

with log as (
select t.*, max(date(end_time))over() as dt from tb_user_video_log t
)

select 
video_id,
round ((rate*100+5*like_num+3*comment_num+2*retweet_num)/(cnt+1),0) as hot_index
from (
select 
 t1.video_id,
 date(t1.end_time) as dt, -- 统计日期
 avg(if(timestampdiff(second,start_time,end_time)>=t2.duration,1,0)) over(partition by t1.video_id) as rate, -- 频完播率
 sum(if(if_like =1,1,0)) over(partition by t1.video_id) as like_num, -- 点赞数
 sum(if(comment_id is not null,1,0)) over(partition by t1.video_id) as comment_num, -- 评论数
 sum(if(if_retweet =1,1,0)) over(partition by t1.video_id) as retweet_num, -- 转发数
 row_number() over(partition by t1.video_id order by end_time) as rn , -- 排序
 min(datediff(dt,date(t1.end_time))) over(partition by t1.video_id ) as cnt -- 播放天数
from log t1 
inner join tb_video_info t2
on t1.video_id = t2.video_id
where datediff(dt,date(t2.release_time)) between 0 and 29
  -- where datediff(date((select max(end_time) from tb_user_video_log)), date(release_time)) <= 29
) tt 
where rn =1 
-- and video_id=2002
order by 2 desc
limit 3
;

发表于 2023-08-16 10:14:02 回复(0)
想问下各位大佬这是什么情况呢,我明明输出的是正确答案,但是不给我通过,对比看预期输出少了2002年?一脸懵逼,我的代码怎么还让预期输出少了一行呢

发表于 2023-07-20 23:58:27 回复(1)
select
    vi.video_id,
    round((100*avg(if(timestampdiff(second,start_time,end_time) >= duration,1,0)) + 
           5*sum(if_like) + 
           3*count(comment_id) + 
           2*sum(if_retweet)) / (datediff(max(date(max(end_time))) over(),date(max(end_time))) + 1)) hot_index
from tb_user_video_log uvl
join tb_video_info vi
on uvl.video_id = vi.video_id
where date(release_time) > (select date_sub(date(max(end_time)),interval 30 day) from tb_user_video_log)
group by vi.video_id
order by hot_index desc
limit 3;

发表于 2023-07-19 17:14:48 回复(0)

问题信息

难度:
219条回答 1597浏览

热门推荐

通过挑战的用户

查看代码
  • 二维码

    扫描二维码,关注牛客网

  • 二维码

    下载牛客APP,随时随地刷题