一、知识点汇总与拓展
先看这个图
开窗函数的框架限定算数我的知识盲区吧,这里正好用到了,顺便完成了一项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;
搞定~