题解 | #试卷完成数同比2020年的增长率及排名变化#

试卷完成数同比2020年的增长率及排名变化

http://www.nowcoder.com/practice/13415dff75784a57bedb6d195262be7b

问题拆分

1.找到各类试卷tag在2020年与2021年上半年的完成次数

    1. 试卷完成信息出现在exam_record表中,试卷类别出现在examination_info中,因此通过right join或者left join两表形成表t1
....
		exam_record t1
    right join
        examination_info t2
    on t1.exam_id = t2.exam_id
....
    1. 由于需要2020年与2021年上半年的数据,在连接表时,使用where筛选submit_time
....
    where
        year(submit_time) in (2021, 2020)
    and
        month(submit_time)<=6
 ....
  • 3.筛选数据后,使用group by 依次对类别tag和答题时间submit_time进行分组,使用count(*)统计每类试卷每年的答题数量;
....
count(*) exam_cnt,
....
group by
        tag,year(submit_time)
....
  • 4.使用over()rank()对每年的各类试卷进行排名,按照试卷完成数倒序排名;
....
rank() over(partition by year(submit_time) order by count(*) desc) exam_cnt_rank
....

形成t1

	select
        tag,
        year(submit_time) start_year,
        count(*) exam_cnt,
        rank() over(partition by year(submit_time) order by count(*) desc) exam_cnt_rank
    from
        exam_record t1
    right join
        examination_info t2
    on t1.exam_id = t2.exam_id
    where
        year(submit_time) in (2021, 2020)
        and
        month(submit_time)<=6
    group by
        tag,year(submit_time)

2.统计同比增长率以及排名变化(在t1表中计算即可)

  • 主要思路:t1中的每类试卷有2020年以及2021年的完成数量,有两行数据,对tag使用group by分组变成一行数据,按照年份start_year使用if()和sum()嵌套进行计算。
  • 注意!!!为保证同类试卷在2020年与2021年都有数据,需要对group by 后的数据使用having进行筛选,满足count(*)=2

eg:计算2020年的试卷完成数量

sum(if(start_year=2020, exam_cnt, 0)) exam_cnt_20

eg:计算同比增长率(2021年完成数量减去2020年完成数量,再除以2020年完成数量)

sum(if(start_year=2020, -exam_cnt, exam_cnt))/sum(if(start_year=2020, exam_cnt, 0))

  • 该部分统计代码
	sum(if(start_year=2020, exam_cnt, 0)) exam_cnt_20,
    sum(if(start_year=2021, exam_cnt, 0)) exam_cnt_21,
    concat(round(100*sum(if(start_year=2020, -exam_cnt, exam_cnt))/sum(if(start_year=2020, exam_cnt, 0)),1), '%') growth_rate,
    sum(if(start_year=2020, exam_cnt_rank, 0)) exam_cnt_rank_20,
    sum(if(start_year=2021, exam_cnt_rank, 0)) exam_cnt_rank_21,
    sum(if(start_year=2020, -exam_cnt_rank, exam_cnt_rank)) rank_delta

总体代码

select
    tag,
    sum(if(start_year=2020, exam_cnt, 0)) exam_cnt_20,
    sum(if(start_year=2021, exam_cnt, 0)) exam_cnt_21,
    concat(round(100*sum(if(start_year=2020, -exam_cnt, exam_cnt))/sum(if(start_year=2020, exam_cnt, 0)),1), '%') growth_rate,
    sum(if(start_year=2020, exam_cnt_rank, 0)) exam_cnt_rank_20,
    sum(if(start_year=2021, exam_cnt_rank, 0)) exam_cnt_rank_21,
    sum(if(start_year=2020, -exam_cnt_rank, exam_cnt_rank)) rank_delta
from
    (select
        tag,
        year(submit_time) start_year,
        count(*) exam_cnt,
        rank() over(partition by year(submit_time) order by count(*) desc) exam_cnt_rank
    from
        exam_record t1
    right join
        examination_info t2
    on t1.exam_id = t2.exam_id
    where
        year(submit_time) in (2021, 2020)
        and
        month(submit_time)<=6
    group by
        tag,year(submit_time)) t1
group by
    tag
having
    count(*) = 2
order by
    growth_rate desc, exam_cnt_rank_21 desc;
全部评论
为什么是这个呢?concat(round(100*sum(if(start_year=2020, -exam_cnt, exam_cnt))/sum(if(start_year=2020, exam_cnt, 0)),1), '%') growth_rate, 换成concat(round(100*sum(if(start_year=2021, exam_cnt,0))/sum(if(start_year=2020, exam_cnt, 0)),1), '%') growth_rate,结果就不对了,不明白,求解答
点赞 回复 分享
发布于 2023-07-07 17:58 河南
请问大神having count(*) = 2 有相关介绍吗?没太看懂
点赞 回复 分享
发布于 2022-10-31 16:47 上海
小白来学习
点赞 回复 分享
发布于 2022-05-27 13:22
sum(if(start_year=2020, exam_cnt, 0)) exam_cnt_20,为什么所有都是求和呢,if(start_year=2020, exam_cnt)exam_cnt_20这样子有问题吗,求解答,谢谢
点赞 回复 分享
发布于 2022-05-27 13:21
having count(*) = 2 这里是什么意思呀
点赞 回复 分享
发布于 2022-05-27 13:20

相关推荐

秋招投简历提醒助手:个人经验是,一般面二十场左右就会进入侃侃而谈阶段。我今年七月末的时候开始的第一次面试,都是很多不会,回复很慢。后面慢慢迭代,到九月中的时候基本上面啥说啥,很放松的状态
远程面试的尴尬瞬间
点赞 评论 收藏
分享
评论
15
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务