【思路】
- 按tag统计2021年上半年的完成数,排名情况,作为表t1
- 按tag统计2021年上半年的完成数,排名情况,作为表t2
- t1 inner join t2 using(tag)关联出20上半年和21上半年都有作答的tag
- 基于t1和t2,再外层嵌一层查询,计算同比增长率,排名变化率等
【知识点】
- rank()over() 跳过相同几个排名
- inner join 灵活使用表联结查询
- with [table] as (...) 创建一个临时使用的表,不创建的话,可以用表联结或者子查询
- cast(x as type) 转换x的数据类型
【易错点】
- 注意排名用rank()over(),跳过相同的几个的排名
- 计算排名变化的时候,有负数,需要转换数据类型
- 一般默认定义的数据类型为signed(有符号类型),取值返回包含有负数范围,一般正负值的差依然等于无符号类型的范围的上限值
- 当定义为unsigned(无符号类型)时, 取值范围仅为正数范围,下限值为0;
- 当设置为unsigned时候,报错BIGINT UNSIGNED value is out of range….,所以需要转换成signed
【代码】
with t1 as (select tag, count(score) as 2021_exam_cnt, rank() over(order by count(score) desc) as 2021_dranking from exam_record er1 join examination_info ei1 using(exam_id) where year(start_time)=2021 and month(start_time) between 1 and 6 group by tag) select tag, 2020_exam_cnt, 2021_exam_cnt, concat(round(((2021_exam_cnt-2020_exam_cnt)/2020_exam_cnt)*100,1),'%')as growth_rate, 2020_dranking, 2021_dranking, cast(t1.2021_dranking as signed)-cast(t2.2020_dranking as signed) as rank_delta from( select tag, count(score) as 2020_exam_cnt, rank() over(order by count(score) desc) as 2020_dranking from exam_record er2 join examination_info ei2 using(exam_id) where year(start_time)=2020 and month(start_time) between 1 and 6 group by tag )t2 join t1 using(tag) order by growth_rate desc,2021_dranking desc