题解 | #未完成率较高的50%用户近三个月答卷情况#

未完成率较高的50%用户近三个月答卷情况

https://www.nowcoder.com/practice/3e598a2dcd854db8b1a3c48e5904fe1c

花了 1.5小时的题目还是值得我纪念一下。。其中前一个小时我都在“去重”的坑里。。

看到解释表中的第二行——用户 1002未完成数、作答总数分别是 4、8,而不是 5、9。我找了半天原因,于是在 exam_record 表中发现了这样两行(牛客这自带插入表格真难用😥):

id

uid

exam_id

start_time

submit_time

score

10

1002

9002

2020-02-02 12:01:01

None

None

11

1002

9002

2020-02-02 12:01:01

2020-02-02 12:43:01

81

因此我以为需要先去重(即 uid 用户ID, exam_id 试卷ID, start_time 开始作答时间,这三项完全一致的为重复行,现实生活中这样认为也比较合理,例如重定向导致的重复行)。

去重:

  1. 首先用 dense_rank 根据 uid, exam_id, start_time 排序编号,并按 submit_time倒叙排序,记为 t1。这样属于重复行的可以编号相同,并且submit_time 不为空的会优先排在该组的第一行;
  2. 然后用 row_number 以dr分组,根据 uid, exam_id, start_time 排序编号,记为 t2;
  3. 最后筛选出 t2 中的 rk = 1 即为去重结果。

with t as
(
    select *
    from
    (
        select *, row_number() over(partition by dr order by uid, exam_id, start_time) rk
        from 
        (
            select *, dense_rank() over(order by uid, exam_id, start_time) dr
            from exam_record  
            order by dr, submit_time desc
        )t1
    )t2
    where rk=1
)

结果一个小时过去了,案例不通过,重读题目,嗯????SQL试卷?!?tnnd

with a1 as
(
    select uid, sum(if(submit_time is null, 1, 0)) incomplete_cnt, 
    count(*)    total_cnt, 
    sum(if(submit_time is null, 1, 0))/count(*) incomplete_rate,
    PERCENT_RANK() over(order by sum(if(submit_time is null, 1, 0))/count(*) desc) rk
    from exam_record
    left join examination_info using(exam_id)
    where tag='SQL'
    group by uid
)


select uid,	start_month,	total_cnt,	complete_cnt
from
(
    select uid, date_format(start_time, '%Y%m') start_month, count(start_time) total_cnt, sum(if(submit_time is not null,1,0)) complete_cnt,
    row_number() over(partition by uid order by date_format(start_time, '%Y%m') desc)  time_rk
    from exam_record
    where uid in
    (
        select uid
        from a1
        left join user_info using(uid)
        where rk<=0.5
        and (level=6 or level=7)
    )
    group by uid, start_month
)a2
where  time_rk<=3 # 查找作答时间最近的3个月
order by uid, start_month
;

划重点:

  1. PERCENT_RANK() 用得比较少,新知识点
  2. 查找作答时间最近的3个月,可以用排序编号的方法选出前三,根选出每个部门工资前三的员工的题目思路类似。
全部评论

相关推荐

码农索隆:这种hr,建议全中国推广
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-01 11:47
点赞 评论 收藏
分享
重生我想学测开:嵌入式的问题,我准备入行京东外卖了
点赞 评论 收藏
分享
05-11 11:48
河南大学 Java
程序员牛肉:我是26届的双非。目前有两段实习经历,大三上去的美团,现在来字节了,做的是国际电商的营销业务。希望我的经历对你有用。 1.好好做你的CSDN,最好是直接转微信公众号。因为这本质上是一个很好的展示自己技术热情的证据。我当时也是烂大街项目(网盘+鱼皮的一个项目)+零实习去面试美团,但是当时我的CSDN阅读量超百万,微信公众号阅读量40万。面试的时候面试官就告诉我说觉得我对技术挺有激情的。可以看看我主页的美团面试面经。 因此花点时间好好做这个知识分享,最好是单拉出来搞一个板块。各大公司都极其看中知识落地的能力。 可以看看我的简历对于博客的描述。这个帖子里面有:https://www.nowcoder.com/discuss/745348200596324352?sourceSSR=users 2.实习经历有一些东西删除了,目前看来你的产出其实很少。有些内容其实很扯淡,最好不要保留。有一些点你可能觉得很牛逼,但是面试官眼里是减分的。 你还能负责数据库表的设计?这个公司得垃圾成啥样子,才能让一个实习生介入数据库表的设计,不要写这种东西。 一个公司的财务审批系统应该是很稳定的吧?为什么你去了才有RBAC权限设计?那这个公司之前是怎么处理权限分离的?这些东西看着都有点扯淡了。 还有就是使用Redis实现轻量级的消息队列?那为什么这一块不使用专业的MQ呢?为什么要使用redis,这些一定要清楚, 就目前看来,其实你的这个实习技术还不错。不要太焦虑。就是有一些内容有点虚了。可以考虑从PR中再投一点产出
投递美团等公司9个岗位
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

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