# 统计每类试卷在2020年和2021年上半年的做完次数及做完次数排名
select tag,
sum(if(submit_time < '2020-07-01 00:00:00' and year(submit_time) = '2020', 1,0)) as exam_cnt_20,
sum(if(submit_time < '2021-07-01 00:00:00' and year(submit_time) = '2021', 1,0)) as exam_cnt_21,
rank()over(order by sum(if(submit_time < '2020-07-01 00:00:00' and year(submit_time) = '2020', 1,0)) desc) as exam_cnt_rank_20,
rank()over(order by sum(if(submit_time < '2021-07-01 00:00:00' and year(submit_time) = '2021', 1,0)) desc) as exam_cnt_rank_21
from examination_info ei 
join (select * from exam_record where submit_time is not null) k
on ei.exam_id = k.exam_id
group by tag


# -----------------------------------完整代码------------------------------------
select tag, exam_cnt_20, exam_cnt_21,
concat(round((exam_cnt_21-exam_cnt_20)/exam_cnt_20*100,1),'%') as growth_rate,
exam_cnt_rank_20, exam_cnt_rank_21, CONVERT(exam_cnt_rank_21, SIGNED)-CONVERT(exam_cnt_rank_20, SIGNED) as rank_delta
from (
    select tag,
    sum(if(submit_time < '2020-07-01 00:00:00' and year(submit_time) = '2020', 1,0)) as exam_cnt_20,
    sum(if(submit_time < '2021-07-01 00:00:00' and year(submit_time) = '2021', 1,0)) as exam_cnt_21,
    rank()over(order by sum(if(submit_time < '2020-07-01 00:00:00' and year(submit_time) = '2020', 1,0)) desc) as exam_cnt_rank_20,
    rank()over(order by sum(if(submit_time < '2021-07-01 00:00:00' and year(submit_time) = '2021', 1,0)) desc) as exam_cnt_rank_21
    from examination_info ei 
    join (select * from exam_record where submit_time is not null) k
    on ei.exam_id = k.exam_id
    group by tag
) k1
where exam_cnt_20>0 and exam_cnt_21>0
order by growth_rate desc, exam_cnt_rank_21 desc;

1.注意这里需要统计各类试卷的完成次数,因此不能直接通过筛选submit_time is not null去获取试卷完成记录再分组,这样会导致没有试卷完成记录的试卷类被忽视,从而得不到这类试卷的完成次数。(最好是获得全部种类试卷的完成次数之后,再去根据实际需求进行筛选计算)

2.直接使用排名数相减,会导致查询时两个无符号的字段相减,得到一个负数,会抛出该异常:BIGINT UNSIGNED value is out of range in ....

这时需要用到格式转换将无符号类型转换成有符号类型:select (CONVERT(num1, SIGNED)-CONVERT(num1, SIGNED))

3.用好sum()与if()函数联合使用从而满足需求真的很棒!

4.窗口函数的使用,及rank()与row_number()函数的区别都需要弄清楚哦!