看了这个SQL实战面试题集,打满了鸡血,彷佛一切大厂都是弟弟

今天要分享一点出来的是,飞书文档中的 第40题: 打卡必须给我对准了再打 之 这卡不打也罢,年轻就是资本,我有的是资本

题的来源文档(数据开发必学):https://ykg8hl7h33.feishu.cn/docx/VNo7dJLJfoDwT1xNNVpcLg8Snlc

题目:

求每个员工每天的有效打卡次数,有效打卡定义:首次打卡有效以首次打卡为基准,后续每次打卡间隔应大于等于1小时,同时要求小于3小时

有效打卡定义:

  1. 首次打卡有效
  2. 以首次打卡为基准,后续每次打卡间隔应大于等于1小时,同时要求小于3小时

备注:如果第二次打卡无效了 那第三次还可以和第二次比较

数据:

with data as (
        select '张三' as name , '2024-04-16 08:31:00' as clock_time union all
        select '张三' as name , '2024-04-16 09:32:00' as clock_time union all
        select '张三' as name , '2024-04-16 10:31:00' as clock_time union all
        select '张三' as name , '2024-04-16 11:33:00' as clock_time union all
        select '张三' as name , '2024-04-16 12:35:00' as clock_time union all
        select '张三' as name , '2024-04-16 14:31:00' as clock_time union all
        select '张三' as name , '2024-04-16 15:31:00' as clock_time union all
        select '张三' as name , '2024-04-16 16:31:00' as clock_time union all
        select '张三' as name , '2024-04-16 17:30:00' as clock_time union all
        select '张三' as name , '2024-04-16 18:31:00' as clock_time union all
        select '李四' as name , '2024-04-16 08:33:00' as clock_time union all
        select '李四' as name , '2024-04-16 09:32:00' as clock_time union all
        select '李四' as name , '2024-04-16 10:31:00' as clock_time union all
        select '李四' as name , '2024-04-16 11:33:00' as clock_time union all
        select '李四' as name , '2024-04-16 12:35:00' as clock_time union all
        select '李四' as name , '2024-04-16 16:31:00' as clock_time union all
        select '李四' as name , '2024-04-16 17:30:00' as clock_time union all
        select '李四' as name , '2024-04-16 18:31:00' as clock_time union all
        select '王朝' as name , '2024-04-16 08:33:00' as clock_time union all
        select '王朝' as name , '2024-04-16 09:32:00' as clock_time union all
        select '王朝' as name , '2024-04-16 10:31:00' as clock_time union all
        select '王朝' as name , '2024-04-16 11:33:00' as clock_time union all
        select '王朝' as name , '2024-04-16 12:35:00' as clock_time union all
        select '王朝' as name , '2024-04-16 16:31:00' as clock_time union all
        select '王朝' as name , '2024-04-16 17:30:00' as clock_time union all
        select '王朝' as name , '2024-04-17 17:35:00' as clock_time union all
        select '王朝' as name , '2024-04-16 18:31:00' as clock_time 
)

解题思路:


--解题思路:
--既然首次打卡有效,所以每天的第一条打卡就不用关心
--我们怎么计算第二次以及后面多次是否和上一次的时间范围在  1<=x<3 大于等于1小时,且小于3小时
--我感觉需要拿到上一条数据才行,所以我们按照 name,day 来作分区 取每条数据的上一条,如果上一条数据为null,则无需多言,因为只会影响我的速度(哈哈
--剩下拿到了上一条数据的,我们和当前时间的小时做一个比较即可 1 <= x <3 就是我们的公式
--select 
--        name ,
--        clock_time ,
--        unix_timestamp( clock_time  ) clock_time_second,
--        lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) as prev_time , --拿到每个人在每天的打卡记录上一个时间,为空代表是第一天
--        unix_timestamp( lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) ) as prev_time_second --拿到每个人在每天的打卡记录上一个时间,为空代表是第一天
--from 
--        data
        

--2. 我们和当前时间的小时做一个比较即可 1 <= x <3 就是我们的公式        
--select 
--        name ,
--        clock_time ,
--        lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) as prev_time, --拿到每个人在每天的打卡记录上一个时间,为空代表是第一天
--        --用时间戳去比较
--        if( lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) is null , --为空代表是第一天,直接为有效
--                true,
--                if(
--                        --用当前打卡时间 - 上一次打卡时间 = 与上次打卡的时间差
--                        ( unix_timestamp( clock_time  ) - unix_timestamp( lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) ) ) >= 60*60 and  -- >=60*60 = 大于1小时
--                        ( unix_timestamp( clock_time  ) - unix_timestamp( lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) ) ) < 60*60*3 ,    -- <60*60*3 = 小于3小时
--                        true,
--                        false
--                )
--        ) as is_valid -- 是否有效打卡
--from 
--        data
        
        
--3. 对有效状态进行聚合
select
        name,
        to_date(clock_time),
        count(is_valid) as day_total_valid_cnt
from(
        select 
                name ,
                clock_time ,
                --用时间戳去比较
                if( lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) is null , --为空代表是第一天,直接为有效
                        true,
                        if(
                                --用当前打卡时间 - 上一次打卡时间 = 与上次打卡的时间差
                                ( unix_timestamp( clock_time  ) - unix_timestamp( lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) ) ) >= 60*60 and  -- >=60*60 = 大于1小时
                                ( unix_timestamp( clock_time  ) - unix_timestamp( lag(clock_time) over(partition by name , to_date(clock_time) order by clock_time asc) ) ) < 60*60*3 ,    -- <60*60*3 = 小于3小时
                                true,
                                false
                        )
                ) as is_valid -- 是否有效打卡
        from 
                data
)t
where is_valid = true
group by 
        name,
        to_date(clock_time)

结果:

#offer##大数据##面试题##面试##笔试#
全部评论

相关推荐

2025-12-27 18:11
已编辑
门头沟学院 前端工程师
28双非鼠鼠第一份实习,感谢金山,感谢面试官张先生的赏识,也感谢自己很开心很开心(有没有待过的前辈,求摸鱼技巧bushi)timeline12.15&nbsp;投递12.16&nbsp;约面12.18&nbsp;一面&nbsp;半个小时后约二面12.19&nbsp;二面,口头oc12.24&nbsp;发offer一面1.&nbsp;开发页面中使用的布局方式2.&nbsp;flex:&nbsp;1&nbsp;是什么的缩写3.&nbsp;水平居中的方法4.&nbsp;tailwindcss&nbsp;的优势5.&nbsp;js&nbsp;的闭包6.&nbsp;打印结果的题,解释为什么(var&nbsp;定义&nbsp;i&nbsp;,setTimeout&nbsp;执行打印),使用&nbsp;let&nbsp;的打印结果7.&nbsp;箭头函数和普通函数的区别8.&nbsp;promise&nbsp;构造函数是同步还是异步9.&nbsp;内存泄漏的情况10.&nbsp;interface&nbsp;和&nbsp;type&nbsp;的区别11.&nbsp;react&nbsp;的&nbsp;key&nbsp;作用12.&nbsp;常用的钩子函数13.&nbsp;怎么避免不必要的渲染14.&nbsp;useeffect&nbsp;的使用场景15.&nbsp;react&nbsp;和&nbsp;vue&nbsp;怎么选择16.&nbsp;vue&nbsp;的&nbsp;data&nbsp;为什么用函数17.&nbsp;tcp&nbsp;为什么需要三次握手和四次挥手18.&nbsp;vite&nbsp;为什么比较快19.&nbsp;解释防抖节流和手写防抖函数,还有实现思路20.&nbsp;深浅拷贝的区别和手写深拷贝,讲实现思路反问了业务,反馈时间和学习建议二面基本上是围绕项目展开,根据项目的每一项,来给场景题问你会怎么做,跟基础相关的东西如下:1.&nbsp;虚拟列表的实现和原理2.&nbsp;zustand&nbsp;和&nbsp;context&nbsp;的区别3.&nbsp;vitest&nbsp;相关,写测试的话应该怎么做些什么?4.&nbsp;monorepo的细节问题5.&nbsp;做项目的动机6.&nbsp;事件委托和时间冒泡的区别有个点顺着问了我五个问题实在是答不下去了就是说感觉金山云这边面试虽然一面全是八股,但是二面还是要好好准备项目,做到能被深挖那么两三个问题的程度,鼠鼠也是运气很好,问的都是准备过的嘻嘻面试完之后还很期待这个面试官会不会是我mt或者ld,会很认真的听我说话,然后告诉我哪里有小问题,不知道是不是鼠鼠的错觉,感觉他看后辈的眼神都是带有欣赏的意味真的很复合我对mt/ld的幻想(bushi),但是后来发现他ip是北京的qwq有点点小失落,不过没关系,看隔壁某书感觉金山的节奏还挺慢的期待入职ing愿一切顺利,好运常伴吾身这里再吐槽一下流程,怎么!!这么!!慢!!急死我了急死我了!!鬼知道我从周一到接到offer这段时间有多煎熬,哎呀但是但是好在一切如愿
发面经攒人品
点赞 评论 收藏
分享
评论
1
4
分享

创作者周榜

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