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

【场景】:等级值百分比

【分类】:专用窗口函数、多表连接

分析思路

难点:

长整型的数据类型要求不能有负号产生,用cast函数转换数据类型为signed。

(1)统计2020年上半年各类试卷的做完次数

  • [条件]:where date(start_time) between '20200101' and '20200630'
  • [使用]:group by

(2)统计2021年上半年各类试卷的做完次数

  • [条件]:where date(start_time) between '20210101' and '20210630'
  • [使用]:group by

(3)统计2020上半年做完次数排名

  • [使用]:rank()

(4)统计2021上半年做完次数排名

  • [使用]:rank()

(5)统计每个用户增长率、做完次数排名变化,按增长率和21年排名降序输出

使用左连接相当于where条件exam_cnt_20 is not null

  • [条件]:exam_cnt_21 is not null
  • [使用]:left join

注意: 1.增长率计算公式:(exam_cnt_21-exam_cnt_20)/exam_cnt_20 2.做完次数排名变化(2021年和2020年比排名升了或者降了多少) 3.计算公式:exam_cnt_rank_21-exam_cnt_rank_20 4.条件:exam_cnt_20、exam_cnt_21都不为空 5.长整型的数据类型要求不能有负号产生,所以用cast函数转换数据类型为signed。如果不用cast函数两数相减时一旦产生负数会报错:BIGINT UNSIGNED(长整型数字无符号)。所以要转换数据类型为signed类型,保证产生负数也不会报错。对比增长率,明明相减的时候它也会产生负数,为什么就不用cast处理呢?因为round函数对正数、负数都可以做处理。

扩展

前往查看: MySQL 窗口函数

求解代码

方法一

with子句

with 
    main as(
        #2020年上半年各类试卷的做完次数
        select
            tag,
            '2020' as start_year_20,
            count(start_time) as exam_cnt_20
        from examination_info a,exam_record b
        where a.exam_id = b.exam_id
        and 7 > month(start_time)
        and year(start_time)=2020
        and submit_time is not null
        group by tag
    ),
    attr as(
    #2021年上半年各类试卷的做完次数
        select
            tag,
            '2021' as start_year_21,
            count(start_time) as exam_cnt_21
        from examination_info a,exam_record b
        where a.exam_id = b.exam_id
        and date(start_time) between '20210101' and '20210630'
        and submit_time is not null
        group by tag
    ),
    main1 as(
        #2020上半年做完次数排名
        select
            tag,
            start_year_20,
            exam_cnt_20,
            rank() over (partition by start_year_20 order by exam_cnt_20 desc) as exam_cnt_rank_20
        from main
    ),
    attr1 as(
        #2021上半年做完次数排名
        select
            tag,
            start_year_21,
            exam_cnt_21,
            rank() over (partition by start_year_21 order by exam_cnt_21 desc) as exam_cnt_rank_21
        from attr
    )

#计算2021年上半年各类试卷的做完次数相比2020年上半年同期的增长率(百分比格式,保留1位小数),以及做完次数排名变化,按增长率和21年排名降序输出
select
    tag,
    exam_cnt_20,
    exam_cnt_21,
    concat(round(100*(exam_cnt_21-exam_cnt_20)/exam_cnt_20,1),'%') as growth_rate,
    exam_cnt_rank_20,
    exam_cnt_rank_21,
    cast(exam_cnt_rank_21 as signed)-cast(exam_cnt_rank_20 as signed) as rank_delta
from main1
left join attr1 using(tag)
where exam_cnt_21 is not null
order by growth_rate desc, exam_cnt_rank_21 desc

方法二

多表连接

select
    tag,
    exam_cnt_20,
    exam_cnt_21,
    concat(round(100*(exam_cnt_21-exam_cnt_20)/exam_cnt_20,1),'%') as growth_rate,
    exam_cnt_rank_20,
    exam_cnt_rank_21,
    cast(exam_cnt_rank_21 as signed)-cast(exam_cnt_rank_20 as signed) as rank_delta
from(
    #2020上半年做完次数排名
    select
        tag,
        start_year_20,
        exam_cnt_20,
        rank() over (order by exam_cnt_20 desc) as exam_cnt_rank_20
    from(
        #2020年上半年各类试卷的做完次数
        select
            tag,
            '2020' as start_year_20,
            count(start_time) as exam_cnt_20
        from examination_info a,exam_record b
        where a.exam_id = b.exam_id
        and date_format(start_time,'%Y%m%d') between '20200101' and '20200630'
        and submit_time is not null
        group by tag
    ) main
) main1
left join(
    #2021上半年做完次数排名
    select
        tag,
        start_year_21,
        exam_cnt_21,
        rank() over (order by exam_cnt_21 desc) as exam_cnt_rank_21
    from(
        #2021年上半年各类试卷的做完次数
        select
            tag,
            '2021' as start_year_21,
            count(start_time) as exam_cnt_21
        from examination_info a,exam_record b
        where a.exam_id = b.exam_id
        and substring(start_time,1,10) between '2021-01-01' and '2021-06-30'
        and submit_time is not null
        group by tag
    ) attr
) attr1 using(tag)
where exam_cnt_21 is not null
order by growth_rate desc, exam_cnt_rank_21 desc
全部评论

相关推荐

重生2012之我是java程序员:换个稍微正式点的照片吧
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务