首页 > 试题广场 >

每个创作者每月的涨粉率及截止当前的总粉丝量

[编程题]每个创作者每月的涨粉率及截止当前的总粉丝量
  • 热度指数:167133 时间限制: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-01 10:00:00 2021-09-01 10:00:20
0 1 1 NULL
2 105
2002 2021-09-10 11:00:00
2021-09-10 11:00:30
1 0 1 NULL
3 101
2001 2021-10-01 10:00:00
2021-10-01 10:00:20
1 1 1 NULL
4 102
2001 2021-10-01 10:00:00
2021-10-01 10:00:15
0 0 1 NULL
5 103
2001 2021-10-01 11:00:50
2021-10-01 11:01:15
1 1 0 1732526
6 106 2002 2021-10-01 10:59:05
2021-10-01 11:00:05
2 0 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-01-01 07:00:00
2 2002
901
美食 60 2021-01-01 07:00:00
3 2003
902
旅游 90 2020-01-01 07:00:00
4 2004 902 美女 90 2020-01-01 08:00:00
(video_id-视频ID, author-创作者ID, tag-类别标签, duration-视频时长, release_time-发布时间)

问题:计算2021年里每个创作者每月的涨粉率及截止当月的总粉丝量

  • 涨粉率=(加粉量 - 掉粉量) / 播放量。结果按创作者ID、总粉丝量升序排序。
  • if_follow-是否关注为1表示用户观看视频中关注了视频创作者,为0表示此次互动前后关注状态未发生变化,为2表示本次观看过程中取消了关注。
输出示例
示例数据的输出结果如下

author month fans_growth_rate
total_fans
901 2021-09 0.500 1
901 2021-10
0.250 2

解释:
示例数据中表tb_user_video_log里只有视频2001和2002的播放记录,都来自创作者901,播放时间在2021年9月和10月;其中9月里加粉量为1,掉粉量为0,播放量为2,因此涨粉率为0.500(保留3位小数);其中10月里加粉量为2,掉粉量为1,播放量为4,因此涨粉率为0.250,截止当前总粉丝数为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-01 10:00:00', '2021-09-01 10:00:20', 0, 1, 1, null)
  ,(105, 2002, '2021-09-10 11:00:00', '2021-09-10 11:00:30', 1, 0, 1, null)
  ,(101, 2001, '2021-10-01 10:00:00', '2021-10-01 10:00:20', 1, 1, 1, null)
  ,(102, 2001, '2021-10-01 10:00:00', '2021-10-01 10:00:15', 0, 0, 1, null)
  ,(103, 2001, '2021-10-01 11:00:50', '2021-10-01 11:01:15', 1, 1, 0, 1732526)
  ,(106, 2002, '2021-10-01 10:59:05', '2021-10-01 11:00:05', 2, 0, 0, null);

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

输出

901|2021-09|0.500|1
901|2021-10|0.250|2
select v.author,
       date_format(u.start_time,'%Y-%m') as 'month',

      round((sum(case 
       when u.if_follow=1 then 1 else 0 end) - sum(case  when u.if_follow=2 then 1 else 0 end ))/count(u.start_time),3)  as fans_growth_rate,

    sum(sum(case when u.if_follow = 1 then 1
         when u.if_follow = 2 then -1
         else 0 end) ) over (partition by v.author order by date_format(u.start_time,'%Y-%m')) as fans_total

from tb_video_info as v
left join tb_user_video_log as u
on v.video_id=u.video_id and year(u.start_time)=2021
and year(u.end_time)=2021

group by v.author,month
order by v.author,fans_total
第4字段是抄评论区,这个窗口函数自己写的话一直报错
发表于 2025-06-28 17:43:53 回复(1)
有没有大佬帮忙看下为什么输出的时候author是按正序排的,但是里面month是按倒序排的?怎么修改呢
select b.author,
date_format(a.start_time, '%Y-%m') as month,
round((sum(if(a.if_follow = 1,1,0))-sum(if(a.if_follow = 2, 1, 0)))/count(a.video_id),3) as fans_growth_rate,
sum(sum(if(a.if_follow = 1,1,0))-sum(if(a.if_follow = 2, 1, 0))) over(
    partition by b.author 
    order by date_format(a.start_time,'%Y-%m') asc
) as total_fans
from tb_user_video_log a
left join tb_video_info b on a.video_id = b.video_id
where year(a.start_time) = 2021
group by b.author, month
order by b.author, fans_growth_rate 

发表于 2025-06-23 17:24:54 回复(0)
select author,month,fans_growth_rate,sum(fan) over (partition by author order by month) as total_fans from 
(select author,month,round(sum(fan)/count(1),3) as fans_growth_rate,sum(fan) as fan from 
(select video_id,date_format(start_time,"%Y-%m") as "month",
case when if_follow=1 then 1
     when if_follow=0 then 0
     when if_follow=2 then -1
end as fan 
from tb_user_video_log
WHERE year(start_time) =2021) a 
left join 
(select video_id,author from tb_video_info) b
on a.video_id=b.video_id
group by author,month) as a
order by total_fans




发表于 2025-06-18 18:11:43 回复(0)
 -- 选择需要的列:作者ID、月份、涨粉率和总粉丝数
SELECT
    v.author, -- 作者ID
    DATE_FORMAT (u.start_time, '%Y-%m') AS month, -- 提取开始时间的年月作为月份
    ROUND(
        AVG(
            CASE
                WHEN u.if_follow = 1 THEN 1 -- 如果if_follow为1(关注),则计为+1
                WHEN u.if_follow = 2 THEN -1 -- 如果if_follow为2(取消关注),则计为-1
                ELSE 0 -- 其他情况计为0
            END
        ),
        3 -- 结果保留三位小数
    ) AS fans_growth_rate, -- 计算涨粉率
    SUM(
        SUM(
            CASE
                WHEN u.if_follow = 1 THEN 1 -- 如果if_follow为1(关注),则计为+1
                WHEN u.if_follow = 2 THEN -1 -- 如果if_follow为2(取消关注),则计为-1
                ELSE 0 -- 其他情况计为0
            END
        )
    ) OVER (
        PARTITION BY
            v.author -- 按作者ID分组
        ORDER BY
            DATE_FORMAT (u.start_time, '%Y-%m') -- 按月份排序
    ) AS fans_total -- 计算截止当月的总粉丝数
    -- 从用户-视频互动表tb_user_video_log中选择数据,并将其与短视频信息表tb_video_info进行内连接
FROM
    tb_user_video_log u
    INNER JOIN tb_video_info v ON v.video_id = u.video_id
    -- 过滤条件:筛选出2021年的数据
WHERE
    YEAR (u.start_time) = 2021 -- 开始时间在2021年
    AND YEAR (u.end_time) = 2021 -- 结束时间也在2021年
    -- 按作者ID和月份分组
GROUP BY
    v.author,
    month
    -- 按作者ID和总粉丝数升序排序
ORDER BY
    v.author,
    fans_total;


发表于 2025-05-12 12:00:29 回复(0)
WITH A AS(
    SELECT
        author,
        DATE_FORMAT (start_time,'%Y-%m' ) AS 'month',	
        SUM(CASE
            WHEN if_follow=0 THEN 0
            WHEN if_follow=1 THEN 1
            ELSE -1
        END ) AS new_fans,
        COUNT(*) AS number
    FROM tb_user_video_log u
    JOIN tb_video_info v USING(video_id)
    GROUP BY author,DATE_FORMAT(start_time,'%Y-%m')
)
SELECT
    author,
    month,
    ROUND(new_fans/number,3) AS fans_growth_rate,
    SUM(new_fans) OVER (PARTITION BY author ORDER BY month) AS total_fans
FROM A
where month like '2021%'
ORDER BY author, total_fans

发表于 2024-12-28 20:28:20 回复(0)
两步走 好理解点
-- 使用 CTE (公共表表达式) 来计算每个月的粉丝变化和每月记录数
WITH t1 AS (
    SELECT
        -- 获取作者ID
        author,
        -- 按年月格式化时间,生成月份字段
        date_format(start_time, '%Y-%m') AS month,
        
        -- 计算每个月的粉丝变化数量
        SUM(
            CASE 
                WHEN if_follow = 1 THEN 1  -- 如果是关注,粉丝增加 1
                WHEN if_follow = 2 THEN -1 -- 如果是取关,粉丝减少 1
                ELSE 0                     -- 其他情况不做变化
            END
        ) AS fans_change_num,
        
        -- 计算每月的总记录数,表示每月的视频日志条数
        COUNT(*) AS month_total
    FROM tb_user_video_log log  -- 用户视频日志表
    JOIN tb_video_info info     -- 视频信息表
    USING(video_id)             -- 通过 video_id 关联
    WHERE YEAR(start_time) = 2021 -- 只选择 2021 年的数据
    GROUP BY author, month        -- 按作者和月份进行分组
)

-- 主查询:根据 CTE 中的数据计算粉丝增长率和累计粉丝数
SELECT
    author,  -- 输出作者ID
    month,   -- 输出月份
    
    -- 计算粉丝增长率,如果该月的记录数大于 0,则计算增长率;否则返回 0
    CASE 
        WHEN month_total > 0 THEN ROUND(fans_change_num / month_total, 3)  -- 除以月记录数并保留 3 位小数
        ELSE 0  -- 如果月记录数为 0,则粉丝增长率为 0
    END AS fans_growth_rate,
    
    -- 计算每个作者的累计粉丝变化,按月累计
    SUM(fans_change_num) OVER (PARTITION BY author ORDER BY month) AS total_fans
    
FROM t1  -- 从 CTE 中查询计算结果
ORDER BY author, total_fans;  -- 按作者和累计粉丝数排序


发表于 2024-11-15 11:09:49 回复(0)
这题写完都要长脑子了,这是中等题吗。。。。
select author,`date`,fans_growth_rate,sum(total)over(partition by author order by `date`) total_fans
from
(select distinct author,`date`,round(sum(if_follow)over(partition by author,`date` order by `date`)/count(*)over(partition by author,`date` order by `date`),3) fans_growth_rate,sum(if_follow)over(partition by author,`date` order by `date`) total
from
(select t1.video_id,author,(case when if_follow=0 then 0 when if_follow=1 then 1 else -1 end) if_follow,date_format(start_time,'%Y-%m') `date`
from tb_user_video_log t1
left join tb_video_info t2
on t1.video_id=t2.video_id
where year(start_time)=2021) t3)  t4
order by author,total_fans
发表于 2024-11-05 15:18:04 回复(0)
with t1 as (select video_id, date_format((start_time),'%Y-%m')month,if_follow, (case when if_follow=1 then 1 when if_follow =2 then -1 else 0 end) as cnt,CASE WHEN if_follow = 2 THEN -1
ELSE if_follow END "if_follow_num" from tb_user_video_log)


select b.author,a.month,round(sum(a.cnt)/count(a.video_id),3) as fans_growth_rate,SUM(SUM(a.if_follow_num)) OVER (partition by b.author order by month) "total_fans"
from t1 a
inner join tb_video_info b
on a.video_id = b.video_id
where left(a.month,4) = 2021
group by a.month, b.author
order by b.author, total_fans
发表于 2024-10-27 14:03:43 回复(0)
#2021年 每个创作者 每月  涨粉率 + 截止当月的总粉丝量
#1 涨粉 0 没关注 2 掉粉
select  author,month,	fans_growth_rate,
        sum(fans_growth) over(partition by author
                                order by month) total_fans
from (
        select
            v.author,
            date_format(u.start_time,"%Y-%m") month,
            round(sum(case when if_follow= 1 then 1
                    when if_follow=2 then -1
                    else 0 end) /count(u.uid),3) 	fans_growth_rate,
            sum(case when if_follow= 1 then 1
                    when if_follow=2 then -1
                    else 0 end) fans_growth
        from tb_video_info v
        left join tb_user_video_log u
            on v.video_id = u.video_id and year(u.start_time) = 2021
        where u.video_id is not null
        group by v.author,date_format(u.start_time,"%Y-%m")
) t
order by author,total_fans 


发表于 2024-10-26 11:55:46 回复(0)
with cte as (
    select author, left(start_time, 7) as month, 
    sum(case when if_follow = 0 then 0
    when if_follow = 1 then 1
    when if_follow = 2 then -1
    end)as fan_growth, 
    count(if_follow) as played
    from tb_user_video_log u join tb_video_info v
    on u.video_id = v.video_id
    group by author, month
)

select author, month, round(fan_growth/played, 3) as fans_growth_rate, sum(fan_growth) over(partition by author order by month asc) as total_fans
from cte
where left(month,4) = '2021'
order by author asc, total_fans asc

发表于 2024-10-04 22:40:17 回复(0)
感觉2021年以前的粉丝在算累计粉丝的时候也要加上,想了半天写了依托
with t1 as (
    select  v.author, u.start_time,
            case when u.if_follow = 2 then -1
                 when u.if_follow = 1 then 1
                 when u.if_follow = 0 then 0 end as f
    from tb_user_video_log u
    inner join tb_video_info v on u.video_id = v.video_id
),
t2 as (
    -- 累加算累计粉丝量
    select  author,
            start_time,
            sum(f)over(partition by author order by date_format(start_time,'%Y-%m')) total_fans
    from t1
),
t3 as (
    -- t2中累加粉丝量分组
    select distinct author, date_format(start_time,'%Y-%m') month, total_fans
    from t2
    where start_time
    in (
        select  max(u.start_time)
        from tb_user_video_log u
        inner join tb_video_info v on u.video_id = v.video_id
        group by v.author, date_format(start_time,'%Y-%m')
    )
),
t4 as (
    -- 计算涨粉率
    select  author,
            date_format(start_time,'%Y-%m') month,
            round(sum(f)/count(f),3) fans_growth_rate
    from t1
    group by author, date_format(start_time,'%Y-%m')
)
select  t3.author, t3.month, t4.fans_growth_rate, t3.total_fans
from t3
inner join t4 on t3.author = t4.author and t3.month = t4.month
where t3.month like '2021%'
order by t3.author, t3.total_fans
发表于 2024-08-29 10:29:24 回复(0)
给我出!!!  

select c.`作者` as `auther`,c.`月份` as `month`,c.`涨粉率` as `fans_growth_rate`,
       sum(c.`截止当月的总粉丝量`) over (order by c.`月份`) as `total_fans`
from (
select b.author as `作者`,b.`月份`,
       format(round((b.`加粉量`-b.`掉粉量`)/b.播放量,3),3) as `涨粉率`,
       sum(b.`加粉量`)-sum(b.`掉粉量`) as `截止当月的总粉丝量`
from (
select a.author, a.`月份`,
       count(case when a.is_gz = '已关注' then 1 end ) as '加粉量',
       count(case when a.is_gz = '未关注' then 1 end ) as '掉粉量',
       count(a.uid) as '播放量'
from (      
select t.uid,t.video_id,t1.author, t.if_follow, t.start_time,t.end_time,
       case when t.if_follow = '1' then '已关注'
            when t.if_follow = '2' then '未关注'
          else '状态无变化'
       end as is_gz,
       case when substr(t.start_time,1,7) = substr(t.end_time,1,7) then substr(t.start_time,1,7) end as '月份'
from tb_user_video t
left join tb_video_info t1
on   t1.video_id = t.video_id
) a
group by a.author,a.`月份` ) b
group by b.author,b.`月份` ) c
;
发表于 2024-08-28 16:01:41 回复(0)
select 
author 
,date_format(start_time,'%Y-%m') month 
,round(sum(case when if_follow=2 then -1 else if_follow end)/count(start_time),3) fans_growth_rate
,sum(sum(case when if_follow=2 then -1 else if_follow end))over(partition by author order by date_format(start_time,'%Y-%m')) total_fans
from tb_video_info a inner join tb_user_video_log b using(video_id)
where year(start_time)=2021
group by 1,2
order by 1,4


发表于 2024-08-20 11:00:56 回复(0)
家人们,求问这样算每个作者当月的总粉丝量为什么是不对的啊
select author, 
       month,
       round((add_fans-sub_fans)/play_count,3) as fans_growth_rate,
       sum(add_fans-sub_fans) over (partition by author order by month)total_fans 
from( 
select b.author, 
       DATE_FORMAT(a.start_time, '%Y-%m') as month,
       count(a.video_id) as play_count,
       sum(if(a.if_follow=1,1,0)) as add_fans,
       sum(if(a.if_follow=2,1,0)) as sub_fans
from tb_user_video_log a
left join tb_video_info b
using (video_id)
where year(start_time)='2021'
group by b.author, 
         DATE_FORMAT(a.start_time, '%Y-%m')
)c
order by author, total_fans

发表于 2024-07-29 18:50:06 回复(0)
select author, month, fans_growth_rate, SUM(fans_acc) OVER (partition by author order by month) as fans_acc_cnt
from(
select author, month, round((acf + dcf) / num_play, 3) as fans_growth_rate, acf+dcf as fans_acc
from (
    select author,DATE_FORMAT(start_time, '%Y-%m') AS month, 
    sum(case when if_follow = 1 then 1 else 0 end) as acf,
    sum(case when if_follow = 2 then -1 else 0 end) as dcf,
    count(*) as num_play
    from tb_user_video_log 
    left join tb_video_info on 
    tb_user_video_log.video_id = tb_video_info.video_id
    where year(start_time) = 2021
    group by author, month
) as fans_info
) as final
order by author, fans_acc_cnt

发表于 2024-07-19 18:34:39 回复(0)
用了一个子查询
select author,month,round(fans_growth_rate,3),sum(num) over(partition by author order by month) sum_num from(
    select author,date_format(start_time,'%Y-%m') month,
    sum(if(if_follow=1,1,if(if_follow=2,-1,0)))/count(if_follow) fans_growth_rate,
    sum(if(if_follow=1,1,if(if_follow=2,-1,0))) num
    from tb_user_video_log t
    left join tb_video_info v
    on v.video_id=t.video_id
    where year(start_time)=2021
    group by author,date_format(start_time,'%Y-%m')
) t
order by author,sum_num

发表于 2024-06-25 23:55:34 回复(0)
这样做出错在哪?
select author,month,round(fen,3),sum(num)over(partition by author order by month) as total_fans
from (
    select
        author,
        date_format (start_time,'%Y-%m') as month,
        sum(
            case
                when if_follow = 1 then 1
                when if_follow = 2 then -1
                else 0
            end
        ) / count(a.video_id) as fen,
        sum(
            case
                when if_follow = 1 then 1
                when if_follow = 2 then -1
                else 0
            end
        ) as num
    from
        tb_user_video_log a
        join tb_video_info b on a.video_id = b.video_id
        where year(start_time)=2021
    group by
        author,
        date_format (start_time, '%Y-%m')
) b

发表于 2024-05-22 15:42:42 回复(1)