题解 | #国庆期间每类视频点赞量和转发量#

国庆期间每类视频点赞量和转发量

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

一、知识点汇总与拓展

先看这个图

开窗函数的框架限定算数我的知识盲区吧,这里正好用到了,顺便完成了一项SQL的查缺补漏。
  • rows n perceding:从当前行到前n行(一共n+1行)
  • rang/rows between 边界规则1 and 边界规则2:rang表示按照值的范围进行定义框架,rows表示按照行的范围进行定义框架
rows between 2 perceding and 2 following #当前行往前2行+当前行+当前行往后2行(一共5行)
rows between 1 following 3 following #当前行的后1——>后3(共3行)
rows between unbounded preceding and current row #从第一行到当前行

二、解题步骤

整体的解题思路,首先查询每个tag每天的点赞量,再使用窗口函数进行框架限定查询。
  • 本题的难点主要是查看7天内的累计点赞数,以及对比7天内的转发量最大日。
1)由题意可知,时间范围是9.25-10.1(目的为了缩小查询范围)
  • 10月1日近一周的数据为9.25-10.1
  • 10月2日近一周的数据为9.26-10.1
  • 10月3日近一周的数据为9.27-10.3
DATEDIFF('2021-10-03',DATE_FORMAT(start_time,'%Y-%m-%d'))<9 #限定日期
2)查询在规定日期内,每类tag每天的点赞(like_cnt)和转发数据(ret_cnt)
SELECT  tag,DATE_FORMAT(start_time,'%Y-%m-%d') dt,
		SUM(if_like) like_cnt, #每类tag每天的点赞数据
        SUM(if_retweet) ret_cnt #每类tag每天的转发数据
FROM tb_user_video_log JOIN tb_video_info USING(video_id)
WHERE DATEDIFF('2021-10-03',DATE_FORMAT(start_time,'%Y-%m-%d'))<9
GROUP BY  dt,tag;

3)接下来统计7天内的累计点赞,以及7天内转发的最大值
  • 直接用窗口函数进行限定 rows 6 preceding:从当前行+往前6行
SUM(like_cnt)OVER(PARTITION BY tag ORDER BY dt ROWS 6 PERCEDING)
 #按照日期顺序,一行一行向下进行每日点赞数累加,每7行为一个窗口框架进行数据累加

SUM(ret_cn)OVER(PARTITION BY tag ORDER BY dt ROWS 6 PERCEDING)
 #按照日期顺序,进行大小比较,每7行为一个窗口框架,进行数据比较
  • 带入 like_cnt,ret_cnt,dt 几个定义
SUM(SUM(if_like))OVER(PARTITION BY tag ORDER BY DATE_FORMAT(start_time,'%Y-%m-%d') rows 6 preceding) AS sum_like_cnt_7d
#得出7天内每类tag的点赞数据
	
MAX(SUM(if_retweet))OVER(PARTITION BY tag ORDER BY DATE_FORMAT(start_time,'%Y-%m-%d') rows 6 preceding) AS 	max_retweet_cnt_7d
#得出7天内每类tag转发量最大的日期
#带入完整查询
SELECT  tag,DATE_FORMAT(start_time,'%Y-%m-%d') dt,
	SUM(SUM(if_like))OVER(PARTITION BY tag ORDER BY DATE_FORMAT(start_time,'%Y-%m-%d') rows 6 preceding) AS sum_like_cnt_7d,
    MAX(SUM(if_retweet))OVER(PARTITION BY tag ORDER BY DATE_FORMAT(start_time,'%Y-%m-%d') rows 6 preceding) AS 	max_retweet_cnt_7d
FROM tb_user_video_log JOIN tb_video_info USING(video_id)
WHERE DATEDIFF('2021-10-03',DATE_FORMAT(start_time,'%Y-%m-%d'))<9
GROUP BY dt,tag

4)接下来取出10-1到10-3的数据并按视频类别降序、日期升序排序。
WITH t1 AS (
SELECT  tag,DATE_FORMAT(start_time,'%Y-%m-%d') dt,
		SUM(SUM(if_like))OVER(PARTITION BY tag ORDER BY DATE_FORMAT(start_time,'%Y-%m-%d') rows 6 preceding) AS sum_like_cnt_7d	,
        MAX(SUM(if_retweet))OVER(PARTITION BY tag ORDER BY DATE_FORMAT(start_time,'%Y-%m-%d') rows 6 preceding) AS 	max_retweet_cnt_7d
FROM tb_user_video_log JOIN tb_video_info USING(video_id)
WHERE DATEDIFF('2021-10-03',DATE_FORMAT(start_time,'%Y-%m-%d'))<9
GROUP BY  dt,tag
)
SELECT * FROM t1 WHERE dt BETWEEN '2021-10-01' AND '2021-10-03' ORDER BY tag DESC,dt ASC;

搞定~
SQL解题集 文章被收录于专栏

这是牛客SQL相关的解题集

全部评论
有一个问题:如果存在数据缺失或者数据本来就是有间断的,比如9.27数据为空,该怎么处理近一周呢?
5 回复 分享
发布于 2023-02-14 10:29 北京
每次看题解指定看你的
3 回复 分享
发布于 2022-11-16 10:19 广东
可以作为官方解答了!赞赞赞
2 回复 分享
发布于 2022-10-07 15:00 上海
谢谢大佬,这个讲解很清晰!
2 回复 分享
发布于 2022-04-13 20:51
sum(sum(a.if_like)) over(partition by b.tag order by date_format(a.start_time, '%Y-%m-%d') range interval 6 day preceding) sum_like_cnt_7d 大佬能解释一下吗,用range来限定日期不可以吗?一直提示错误。。
1 回复 分享
发布于 2023-10-19 21:32 北京
不使用外层查询 直接在第3步中采用having dt betweent '2021-10-01' and '2021-10-03'过滤分组聚合后的结果 为什么不可以呢?
1 回复 分享
发布于 2023-02-28 18:05 北京
点赞 回复 分享
发布于 2024-12-27 11:29 河北
我有个疑问,实际生活中很可能存在,最近7天内有一天没有转发的数据,那还能用WHERE DATEDIFF('2021-10-03',DATE_FORMAT(start_time,'%Y-%m-%d'))<9吗? 此代码需要最近7天内,都有数据转发记录这个条件才对吧?
点赞 回复 分享
发布于 2024-08-22 17:58 湖北
写的超级清晰,感谢~
点赞 回复 分享
发布于 2024-05-31 14:51 江苏
rang应该写成range
点赞 回复 分享
发布于 2023-10-18 21:39 新疆
WHERE DATEDIFF('2021-10-03',DATE_FORMAT(start_time,'%Y-%m-%d'))<9. If you delete this where clause, it also works base on this given dataset. However, I guess, in the real work place, it might take more time to run it if you fail to add this where clause. Thank you.
点赞 回复 分享
发布于 2023-09-16 00:48 美国
厉害,原来group by 先执行,窗口函数后执行
点赞 回复 分享
发布于 2023-06-27 16:59 海南
第六行为什么是<9 啊
点赞 回复 分享
发布于 2023-03-06 18:13 江苏
中间3)的preceding拼错了
点赞 回复 分享
发布于 2023-03-05 11:56 上海
请问,题目是7天内单日的最大转发量,为什么要对if_retweet进行累加
点赞 回复 分享
发布于 2023-03-03 15:37 江苏
1.关联两表 按tag,时间分组设置where过滤条件 取各日期点赞量及转发量最大值 2.在对1产生的结果进行窗口函数取7天内结果 3.在设置查询条件10-01-10-03 select tag, dt,sum_like_cnt_7d, max_retweet_cnt_7d from( select tag, dt, sum(likes_cnt) over(partition by tag order by dt rows 6 preceding) as sum_like_cnt_7d, max(retweets_cnt) over(partition by tag order by dt rows 6 preceding) as max_retweet_cnt_7d from( select tag, date_format(start_time, '%Y-%m-%d') as dt, sum(if_like) as likes_cnt, sum(if_retweet) as retweets_cnt from tb_user_video_log t join tb_video_info t1 on t.video_id = t1.video_id where datediff('2021-10-03', start_time)<9 group by tag,dt) a order by tag desc, dt asc) as b where date(dt) between '2021-10-01' and '2021-10-03'
点赞 回复 分享
发布于 2023-03-01 14:12 北京
运行出错 怎么回事啊啊 直接复制的大佬代码啊
点赞 回复 分享
发布于 2022-10-30 11:26 陕西
花了好久在思考怎么用limit跟窗口函数配合,来根据不同部门返回最后3天结果。原来直接时间用来当限制就可以了😭😭。
点赞 回复 分享
发布于 2022-08-11 16:26
WHERE DATE(start_time) BETWEEN DATE_ADD('2021-10-01', INTERVAL -6 DAY) AND '2021-10-03' 这样好像更不容易出错诶~单纯数时间间隔我总感觉我脑子转不过来233
点赞 回复 分享
发布于 2022-05-31 18:22

相关推荐

点赞 评论 收藏
分享
评论
260
38
分享

创作者周榜

更多
牛客网
牛客企业服务