解法一:

with t_base as (
select month(fdate) as month,user_id,song_id
from play_log
where song_id in (select song_id from song_info where singer_name='周杰伦') and user_id in (select user_id from user_info where age >=18 and age <=25) and year(fdate) = '2022'
order by month
)
,t_base_name as (
select month,song_name
from t_base inner join song_info
on t_base.song_id = song_info.song_id
)

select month,ranking,song_name,play_pv from 
(select month,row_number() over(partition by month order by play_pv desc) as ranking,
song_name,play_pv
from 
(select month,song_name,count(song_name) as play_pv
from t_base_name
group by month,song_name) t1
order by month) t2
where ranking <= 3
order by month,ranking