题解 | 每个月Top3的周杰伦歌曲
每个月Top3的周杰伦歌曲
https://www.nowcoder.com/practice/4ab6d198ea8447fe9b6a1cad1f671503
with cte as(
select month(p.fdate) as month,
row_number() over(partition by month(p.fdate) order by count(*) desc, s.song_id asc) as ranking,
s.song_name,
count(*) as play_pv
from play_log as p
inner join song_info as s on p.song_id = s.song_id
inner join user_info as u on p.user_id = u.user_id
where s.singer_name = '周杰伦'
and year(p.fdate) = 2022
and (u.age between 18 and 25)
group by month(p.fdate),s.song_name,s.song_id
)
select month,
ranking,
song_name,
play_pv
from cte
where ranking between 1 and 3
一道有点难度的窗口函数题,可能还是自己不太会用,记录几点:
1.最初版本是完全自己手打的,但是没跑通,原因是有两个错误:
1.1 在cte里没有用row_number( ),而是在主查询里用了rank(play_gv) over(partition by month(p.fdate)) as ranking,显然实例结果里是没有重复的,所以rank是错的;且在where过滤语句中没敢用别名,导致这部分出了问题;(问了ai发现的)
1.2 没有考虑重复的歌名可能不是同一首歌(比如不同的歌手演唱的版本or同一歌手的不同版本),所以一开始没有在row_numer( )后的order by添加 s.song_id asc 以及group by 后添加 s.song_id 。(根据ai修改1.1后,可以跑通,但是测试算例有一个没pass!看了答案和讨论区才意识到这个问题)
2.记得多用between ... and ...
3.代码整体写下来逻辑比较流畅,除了小错误之外的其他部分都和标答差不多,标答喜欢用嵌套查询,我喜欢cte一点
很开心还是有进步的,暑假天天在工位刷sql形成的思维好像有点用处了。继续加油!
