【牛客】SQL140 未完成率较高的50%用户近三个月答卷情况-窗口函数

描述

现有用户信息表user_info(uid用户ID,nick_name昵称, achievement成就值, level等级, job职业方向, register_time注册时间):

iduidnick_nameachievementleveljobregister_time
11001牛客1号32007算法2020-01-01 10:00:00
21002牛客2号25006算法2020-01-01 10:00:00
31003牛客3号♂22005算法2020-01-01 10:00:00

试卷信息表examination_info(exam_id试卷ID, tag试卷类别, difficulty试卷难度, duration考试时长, release_time发布时间):

idexam_idtagdifficultydurationrelease_time
19001SQLhard602020-01-01 10:00:00
29002SQLhard802020-01-01 10:00:00
39003算法hard802020-01-01 10:00:00
49004PYTHONmedium702020-01-01 10:00:00

试卷作答记录表exam_record(uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分):

iduidexam_idstart_timesubmit_timescore
1100190012020-01-01 09:01:012020-01-01 09:21:5990
15100290012020-01-01 18:01:012020-01-01 18:59:0290
13100190012020-01-02 10:01:012020-01-02 10:31:0189
2100290012020-01-20 10:01:01
3100290012020-02-01 12:11:01
5100190012020-03-01 12:01:01
6100290012020-03-01 12:01:012020-03-01 12:41:0190
4100390012020-03-01 19:01:01
7100290012020-05-02 19:01:012020-05-02 19:32:0090
14100190022020-01-01 12:11:01
8100190022020-01-02 19:01:012020-01-02 19:59:0169
9100190022020-02-02 12:01:012020-02-02 12:20:0199
10100290022020-02-02 12:01:01
11100290022020-02-02 12:01:012020-02-02 12:43:0181
12100290022020-03-02 12:11:01
17100190022020-05-05 18:01:01
16100290032020-05-06 12:01:01

请统计SQL试卷上未完成率较高的50%用户中,6级和7级用户在有试卷作答记录的近三个月中,每个月的答卷数目和完成数目。按用户ID、月份升序排序。

由示例数据结果输出如下:

uidstart_monthtotal_cntcomplete_cnt
100220200231
100220200321
100220200521

解释:各个用户对SQL试卷的未完成数、作答总数、未完成率如下:

uidincomplete_cnttotal_cntincomplete_rate
1001370.4286
1002480.5000
1003111.0000

1001、1002、1003分别排在1.0、0.5、0.0的位置,因此较高的50%用户(排位<=0.5)为1002、1003;

1003不是6级或7级;

有试卷作答记录的近三个月为202005、202003、202002;

这三个月里1002的作答题数分别为3、2、2,完成数目分别为1、1、1。

方法一:使用date_format

with cte as(
    select
    uid
    from
        (select
        uid,incomplete_rate,
        percent_rank() over(order by incomplete_rate) as rnk1
        from
            (select
            uid,
            sum(if(submit_time is null,1,0)) as incomplete_cnt,
            count(start_time) as total_cnt,
            sum(if(submit_time is null,1,0))/count(start_time) as incomplete_rate
            from
            exam_record
            where
            exam_id in (select exam_id from examination_info where tag='SQL')
            group by uid)t
        )t2 left join user_info using(uid)
    where rnk1>=0.5 and level>=6
)

select
uid,start_month,total_cnt,complete_cnt
from
    (select
    uid,date_format(start_time,'%Y%m') as start_month,
    count(start_time) as total_cnt,
    sum(if(submit_time is null,0,1)) as complete_cnt,
    dense_rank() over (partition by uid order by date_format(start_time,'%Y%m') desc) as rnk2
    from
    exam_record
    where uid in (select uid from cte)
    group by uid,date_format(start_time,'%Y%m'))t
where rnk2<=3
order by uid,start_month

方法二:使用left+replace

with cte as(
    select
    uid
    from
        (select
        uid,incomplete_rate,
        percent_rank() over(order by incomplete_rate) as rnk1
        from
            (select
            uid,
            sum(if(submit_time is null,1,0)) as incomplete_cnt,
            count(start_time) as total_cnt,
            sum(if(submit_time is null,1,0))/count(start_time) as incomplete_rate
            from
            exam_record
            where
            exam_id in (select exam_id from examination_info where tag='SQL')
            group by uid)t
        )t2 left join user_info using(uid)
    where rnk1>=0.5 and level>=6
)

select
uid,
replace(act_time, '-', '') as start_month,
total_cnt,complete_cnt
from
    (select
    uid,left(start_time,7) as act_time,
    count(start_time) as total_cnt,
    sum(if(submit_time is null,0,1)) as complete_cnt,
    dense_rank() over (partition by uid order by date_format (start_time,'%Y%m') desc) as rnk2
    from
    exam_record
    where uid in (select uid from cte)
    group by uid,left(start_time,7))t
where rnk2<=3
order by uid,act_time
  • 25
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值