吐槽 | #连续两次作答试卷的最大时间窗# 我是彩笔

连续两次作答试卷的最大时间窗

http://www.nowcoder.com/practice/9dcc0eebb8394e79ada1d4d4e979d73c

先上全代码,总的来说就是select套了三层

select
    uid,
    d_wy days_window,
   round(count(*)/a_e_cy * d_wy,2) avg_exam_cnt
from (
         select
             uid,
             start_time,
            leade,
             timestampdiff(day,date(start_time),date(leade))+1 d_wyy,
             timestampdiff(day,date(first),date(last))+1 a_e_cyy,
             first_value(timestampdiff(day,date(start_time),date(leade))+1) over(
                 partition by uid
                 order by (timestampdiff(day,date(start_time),date(leade))+1) desc
                 )  d_wy,
             last_value(  timestampdiff(day,date(first),date(last))+1) over(
                 partition by uid
                 order by ( timestampdiff(day,date(first),date(last))+1) desc
                 )  a_e_cy
         FROM (
                  SELECT
                      uid,start_time,
                      first_value(start_time) over(
                          partition by uid
                          order by start_time
                          ) first,
                      lead(start_time,1) over (
                          partition by uid
                          order by start_time
                          ) leade,
                      last_value(start_time) over(
                          partition by uid
                          order by start_time
                          ) last
                  from exam_record
                  where year(start_time) = 2021
              ) t
         )q
where d_wy-1 <> 0
group by
 uid
order by
    days_window desc, round(count(*)/a_e_cy * d_wy,2) desc;
                            

这是最内层形成初始表主要知识点有:

窗口函数

1.first_value() 可以查排序完了第()列第1个,last最后一个

2.lead() 分组中位于当前行后n行(lead)/ 前n行(lag)的记录值

上个图看看就是

alt

因为是今年所以上一个where year(start_time) = 2021

SELECT
                      uid,start_time,
                      first_value(start_time) over(
                          partition by uid
                          order by start_time
                          ) first,
                      lead(start_time,1) over (
                          partition by uid
                          order by start_time
                          ) leade,
                      last_value(start_time) over(
                          partition by uid
                          order by start_time
                          ) last
                  from exam_record
                  where year(start_time) = 2021

第二层就是二次select完了之后计算日期,,就在这里我遇到了一个大坑,那就是不能直接用timestampdiff来计算start_time跟查出来的leade,first,last之间的日期差为什么呢?

来上图! alt

图中第19行 9-2到9-6算的是4天,

有的小伙伴说我没加1,但是你看第六行9-3到9-7 算的是5天,我+1了!!

所以就是时间问题一个是12点到10点,一个就是12点到12点,,

然后正确答案是按照5天算的,这是题目问题,但是没办法,所以我就date(计算的_time)

其实可以直接datediff()我当时猪脑过载了

alt

题出的有问题,,,我找这个错真的是难啊qaq

select
             uid,
             start_time,
            leade,
             timestampdiff(day,date(start_time),date(leade))+1 d_wyy,
             timestampdiff(day,date(first),date(last))+1 a_e_cyy,
             first_value(timestampdiff(day,date(start_time),date(leade))+1) over(
                 partition by uid
                 order by (timestampdiff(day,date(start_time),date(leade))+1) desc
                 )  d_wy,
             last_value(  timestampdiff(day,date(first),date(last))+1) over(
                 partition by uid
                 order by ( timestampdiff(day,date(first),date(last))+1) desc
                 )  a_e_cy

最后一层没啥说的不说了,难受今天这个题真的是让人难受!

全部评论
我一开始也用timestampdiff,这题我竟然做了一整天。。。
3 回复 分享
发布于 2022-02-21 20:42
我也在timestampdiff这里踩坑了qaq
2 回复 分享
发布于 2021-12-05 13:54
第19行 9-2到9-6算的是4天哪里,因为后面的那个时间是十点,前面那个是十二点,所以不会算作差四天的,timestampdiff出来的值就应该是三天,同理第十行的那个timestampdiff给出的结果就是0天,你+1才是1天的
1 回复 分享
发布于 2022-02-26 23:46
感谢感谢 终于知道是哪里的问题了!
点赞 回复 分享
发布于 2022-07-12 10:50
请问你用的是什么软件做这个题的吗,我在牛客网上做好像有些明细不知道在哪显示
点赞 回复 分享
发布于 2022-05-10 09:11

相关推荐

昨天 23:05
武汉大学 Java
点赞 评论 收藏
分享
评论
7
1
分享

创作者周榜

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