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

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

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

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

要求条件:

1)仅限2021年

2)结果按创作者ID、总粉丝量升序排序

指标:

1)涨粉率 = (加粉量 - 掉粉量) / 播放量

2)字段“if_follow” —— 1代表点击关注,0代表未点击关注,2为取消关注

解题思路

第一步:确认2021年中,每个作者、在每一个月中的实际涨粉量 & 播放量,才能求出每个作者在每个月的转粉率

这一步很简单,只需要联结两个表即可,对作者、月份进行GROUP BY。其中唯一需要注意的是,因为字段if_follow的值只有0、1、2,而非可直接用于计算的-1(掉粉)、0(无变化)、1(涨粉),所以这里需要用到CASE WHEN表达式。

SELECT i.author, 
       DATE_FORMAT(l.start_time, '%Y-%m') AS momth, 
       /* 每个作者在每个月的涨粉量为 SUM(CASE if_follow WHEN...),
       而播放量计算就更简单,在表tb_video_info中,字段“author”中,作者id出现多少行就是多少次播放量,
       最后,对两者相除的结果进行四舍五入,保留3位数即可*/
       ROUND(SUM(CASE l.if_follow WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 
       ELSE NULL END) / COUNT(author), 3) AS fans_growth_rate
       
FROM tb_video_info AS i INNER JOIN tb_user_video_log AS l
ON i.video_id = l.video_id

WHERE YEAR(l.start_time) = 2021
GROUP BY i.author, DATE_FORMAT(l.start_time, '%Y-%m')

第二步 2-1:计算每个作者、每个月的总涨粉量

这一步稍微有点复杂,但也不难。

首先,需要知道:如“截止当前的XX量”这种指标,其实都是累计值的计算,累计值的计算一般可以用聚合函数与窗口函数的结合来解决。

所以,在计算这个累计值之前,需要确认的指标是:每个月的总涨粉量 —— 之后再对这个每月总涨粉量进行累计计算。如此一来,就很清晰了,再为总涨粉量select出一个新字段即可

SELECT i.author, 
       DATE_FORMAT(l.start_time, '%Y-%m') AS month, 
       ROUND(SUM(CASE l.if_follow WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 
       ELSE NULL END) / COUNT(author), 3) AS fans_growth_rate,
       /* 每月的总涨粉量,上面已经使用过了,只需要为其单独创建一个字段即可*/
      SUM(CASE l.if_follow WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 ELSE NULL END) AS monthly_growth
      
FROM tb_video_info AS i INNER JOIN tb_user_video_log AS l
ON i.video_id = l.video_id

WHERE YEAR(l.start_time) = 2021
GROUP BY i.author, DATE_FORMAT(l.start_time, '%Y-%m')

第二步 2-2:基于2-1,计算每个作者、截至当前月的总涨粉量(“总涨粉量”就是题目所说的粉丝量)

这一步很简单了,如上述,需要结合聚合函数与开窗函数来解决,把2-1所创建的table命名为t,再从该表中选取字段来进行计算。直接上代码:

SELECT t.author, t.month, t.fans_growth_rate,
		/* 使用SUM()来计算累计即可,需要对author进行分组、月份进行降序,来计算每个作者在每个月中
        所累积的总涨粉量即可 */
       SUM(t.monthly_growth) OVER (PARTITION BY t.author ORDER BY t.month ASC) AS total_fans
FROM

    (SELECT i.author, 
           DATE_FORMAT(l.start_time, '%Y-%m') AS month, 
           ROUND(SUM(CASE l.if_follow WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 
           ELSE NULL END) / COUNT(author), 3) AS fans_growth_rate,
           /* 每月的总涨粉量,上面已经使用过了,只需要为其单独创建一个字段即可*/
          SUM(CASE l.if_follow WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 ELSE NULL END) AS monthly_growth

    FROM tb_video_info AS i INNER JOIN tb_user_video_log AS l
    ON i.video_id = l.video_id

    WHERE YEAR(l.start_time) = 2021
    GROUP BY i.author, DATE_FORMAT(l.start_time, '%Y-%m')) AS t
    
ORDER BY t.author ASC, total_fans ASC 

其实到第二步已经结束了,但是!其实本道题可以写的更加直接 ——

可以看到2-2中,计算每月的累计值,实际上用的是SUM(t.monthly_growth) OVER ...来解决的,而monthly_growth 实际上又是:

SUM(CASE l.if_follow WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 ELSE NULL END)

因此,我们能不能直接一次性查询,而不进行嵌套呢?——of course!请看如下代码:

SELECT i.author, 
       DATE_FORMAT(l.start_time, '%Y-%m') AS momth,
       ROUND(SUM(CASE l.if_follow 
           WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 
           ELSE NULL END) / COUNT(author), 3) AS fans_growth_rate,
           /* 可以看到这里有两层SUM(),最里层的SUM就是计算每月涨粉量,而最外层的SUM(),
           则是用于开窗函数的SUM(),其所运用的对象正是最里面的SUM() */
        SUM(SUM(CASE l.if_follow 
           WHEN 0 THEN 0 WHEN 1 THEN 1 WHEN 2 THEN -1 
           ELSE NULL END)) OVER (PARTITION BY i.author ORDER BY DATE_FORMAT(l.start_time, '%Y-%m') ASC) AS total_fans
FROM tb_video_info AS i INNER JOIN tb_user_video_log AS l
ON i.video_id = l.video_id
WHERE YEAR(l.start_time) = 2021
GROUP BY i.author, DATE_FORMAT(l.start_time, '%Y-%m')
ORDER BY i.author ASC, total_fans ASC;
全部评论
非常清晰,帮我理解了为什么用两次sum. 第一次sum是对单个月粉丝数量求和,外面的sum是对多个月的粉丝数量求和
点赞 回复 分享
发布于 2022-06-05 12:27

相关推荐

就前几天旅游的时候,打开抖音就经常刷到这类视频:以前是高学历学生、老师、主持人,现在做着团播、擦边主播的工作,以及那些经过精心包装的“职业转型”故事——从铺天盖地的VLOG到所谓的“04年夜场工作日记”,这些内容在初中升学、高考放榜等关键时间节点持续发酵。可以说非常直接且精准地在潜移默化地影响着心智尚未成熟的青少年,使其对特殊行业逐渐脱敏。那我就想问了:某些传播公司、平台运营者甚至某些夜场的老板,你们究竟在传递怎样的价值观?点开那些视频,评论区里也是呈现明显的两极分化:一种是​​经济下行论​​:“现在就业市场已经艰难到这种程度了吗?”​​一种是事实反驳派​​:这些创作者往往拥有名校背景,从事着...
牛客刘北:被环境教育的,为了能拿到足够的钱养活自己,不甘心也得甘心,现在的短视频传播的思想的确很扭曲,但是很明显,互联网玩上一年你就能全款提A6,但你全心全意不吃不喝工作一年未必能提A6,但是在高考中考出现这个的确很扭曲,在向大家传播“不上学,玩互联网也可以轻松年入百万”,不是人变了,是社会在变
预测一下26届秋招形势
点赞 评论 收藏
分享
Yki_:你要算时间成本呀,研究生两三年,博士三四年,加起来就五六年了,如果你本科去腾讯干五年,多领五年的年薪,加上公司内涨薪,可能到时候十五年总薪资也跟博士差不多
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
5
收藏
分享

创作者周榜

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