这题逻辑不难,只是需要多层嵌套,参考以下流程:

  1. 找到所有tag在2020,2021上半年的完成数
  2. 计算growth_rate,并生成各tag完成数排名
  3. 取出所有需要的字段,并计算排名变化(2021-2020年,无需取绝对值)
  4. 筛选出2020和2021年均有完成记录的tag,并按题目要求排序

运行时间:38ms, 超过 100% 的用户。

SELECT #第三步:取出所有需要的字段,并计算排名变化(2021-2020年,无需取绝对值)
  tag,
  exam_cnt_20,
  exam_cnt_21,
  growth_rate,
  exam_cnt_rank_20,
  exam_cnt_rank_21,
  CAST(exam_cnt_rank_21 as SIGNED) - CAST(exam_cnt_rank_20 AS SIGNED) rank_delta
FROM (
SELECT #第二步:计算growth_rate,并生成各tag完成数排名
  tag,
  exam_cnt_20,
  exam_cnt_21,
  IFNULL(CONCAT(ROUND((exam_cnt_21 - exam_cnt_20) / exam_cnt_20 * 100, 1), '%'), 0) growth_rate,
  RANK() OVER (ORDER BY exam_cnt_20 DESC) exam_cnt_rank_20,
  RANK() OVER (ORDER BY exam_cnt_21 DESC) exam_cnt_rank_21
  FROM (
  SELECT #第一步:找到所有tag在2020,2021上半年的完成数
    tag,
    SUM(IF(DATE_FORMAT(submit_time, '%Y-%m') BETWEEN '2020-01' AND '2020-06', 1, 0)) exam_cnt_20,
    SUM(IF(DATE_FORMAT(submit_time, '%Y-%m') BETWEEN '2021-01' AND '2021-06', 1, 0)) exam_cnt_21
  FROM exam_record
  LEFT JOIN examination_info ei USING(exam_id)
  GROUP BY 1) t1
) t2
WHERE exam_cnt_20 != 0 AND exam_cnt_21 != 0 # 第四步:筛选出2020和2021年均有完成记录的tag,并按题目要求排序
ORDER BY 4 desc, 6 desc