--合并三个表
--筛选条件:18-25岁,2022年,周杰伦的歌曲
--分组标准:GROUP BY 每个月,每首歌
--计算每首歌的播放次数:count(*) as play_pv
--使用窗口函数 ROW_NUMBER()/DENSCE_RANK()增加ranking这一列, 注意当 play_pv 一样的时候,按照song_id 排序!
--注意1:在包含窗口函数的查询外层使用 GROUP BY,数据库可能会报错,因为窗口函数的结果通常不是聚合的,并且不能直接用于外层 GROUP BY。所以应该在包含窗口函数的子查询或 CTE(公用表表达式)中先应用 GROUP BY,然后在外部查询中使用窗口函数。本代码中是第一个CTE Month_cnt
--注意2:窗口函数ROW_NUMBER() 是在 where 之后执行的,所以我们需要第二个CTE month_rank 来记录ranking.
--
WITH
Month_cnt AS (
SELECT
MONTH(fdate) AS month,
si.song_name,
MAX(si.song_id) as song_id,
COUNT(*) AS play_pv
FROM
play_log AS pl
LEFT JOIN song_info AS si ON pl.song_id = si.song_id
LEFT JOIN user_info AS ui ON pl.user_id = ui.user_id
WHERE
YEAR(pl.fdate) = 2022
AND ui.age >= 18
AND ui.age <= 25
and si.singer_name = '周杰伦'
GROUP BY
MONTH(pl.fdate),
si.song_name
),
month_rank AS (
SELECT
mc.month,
mc.song_name,
mc.play_pv,
ROW_NUMBER() OVER (PARTITION BY mc.month ORDER BY mc.play_pv desc
, mc.song_id) AS ranking
FROM
Month_cnt AS mc
)
SELECT
mr.month,
mr.ranking,
mr.song_name,
mr.play_pv
FROM
month_rank AS mr
WHERE
mr.ranking IN (1, 2, 3)