大厂SQL面试题,连续时间问题

今天分享一个非常常考,同时也不太容易的sql题目类型,求连续时间问题。

这类题的核心是:分组排序,用时间减去排序,如果连续的话他们的差会是相同值
记住下面的表,按照提供的三步思路理清楚里面的数据逻辑,连续时间问题再不会难到你
大厂SQL面试题,连续时间问题_第1张图片

思路:
求解连续天数是面试时非常常考的问题,这类问题有非常巧妙的统一解法,分为3步:

1、为日期排序

  • row number() over (partition by use_id order by date) as rank

2、求日期和排序的差值(diff)

  • 因为日期存在周期,会存在跨月、跨年的情况,故使用datediff最保险
    date_diff(date, rank) as diff

3、求diff出现最多的次数

  • max(count(diff))

面试真题:

表1:audit_log
大厂SQL面试题,连续时间问题_第2张图片
表2:staff_info
大厂SQL面试题,连续时间问题_第3张图片
表3:category_dict
大厂SQL面试题,连续时间问题_第4张图片
题目:
1)查询近一周分天各部门员工审核量、审核业务类型量、审核来源量,并按日期升序、审核量降序排列
2)查询近7天平均审核时长大于200s的部门中平均审核时长大于400的员工信息(审核时长=审核完成时间-开始审核时间)
3)查询各业务类型中,审核量Top3的员工姓名、员工部门,以及相应的审核通过占比
4)查询连续审核大于等于3天的员工信息:部门、姓名、id

-- 1)查询近一周分天各部门员工审核量、审核业务类型量、审核来源量,并按日期升序、审核量降序排列
select date(FROM_UNIXTIME(start_time)) 日期, 
audito_staf_id,
count(*) 员工审核量,  
count(distinct object_category) 审核业务类型量,  
count(distinct origin) 审核来源量

from audit_log al
WHERE date(FROM_UNIXTIME(start_time)) > DATE_SUB(CURDATE(), INTERVAL 7 DAY)  
GROUP BY 日期, audito_staf_id
ORDER BY 日期, 审核来源量 desc;

-- 2)查询近7天平均审核时长大于200s的部门中平均审核时长大于400的员工信息(审核时长=审核完成时间-开始审核时间)
select b.*
from
(select department_id
from audit_log al
join staff_info si on al.audito_staf_id = si.staff_id
WHERE date(FROM_UNIXTIME(start_time)) > DATE_SUB(CURDATE(), INTERVAL 7 DAY)  
GROUP BY department_id HAVING avg(timestampdiff(SECOND,FROM_UNIXTIME(start_time),FROM_UNIXTIME(create_time))) > 200) a
join 
(select department_id, si.staff_id, staff_name
from audit_log al
join staff_info si on al.audito_staf_id = si.staff_id
WHERE date(FROM_UNIXTIME(start_time)) > DATE_SUB(CURDATE(), INTERVAL 7 DAY)  
GROUP BY department_id, si.staff_id HAVING avg(timestampdiff(SECOND,FROM_UNIXTIME(start_time),FROM_UNIXTIME(create_time))) > 400 ) b on a.department_id = b.department_id

-- 3)查询各业务类型中,审核量Top3的员工姓名、员工部门,以及相应的审核通过占比
select a1.*
from
(select a.*,
row_number() over (partition by object_category order by 员工审核量 desc) as rank_num
from
(select
object_category,
audito_staf_id,
staff_name,
department_id,
count(*) 员工审核量,  
-- sum(if(al.status = 1,1,0) ) 审核通过,
sum(if(al.status = 1,1,0) ) / count(*) 审核通过占比

from audit_log al
join staff_info si on al.audito_staf_id = si.staff_id
GROUP BY object_category, audito_staf_id) a) a1
where rank_num >= 3;


-- 4)查询连续审核大于等于3天的员工信息:部门、姓名、id
SELECT distinct department_name, staff_name, a3.audito_staf_id
from 
(select audito_staf_id, 
date_sub(date,  INTERVAL rank_num DAY) as gap,
count(1) as 连续审核天数
(select *,
row_number() over (partition by user_id order by 日期) as rank_num
from 
(select distinct audito_staf_id, date(FROM_UNIXTIME(start_time)) 日期
from audit_log ) a1
GROUP BY audito_staf_id) a2
GROUP BY audito_staf_id, gap ) a3
join staff_info si on a3.audito_staf_id = si.staff_id
WHERE 连续审核天数 >= 3;

你可能感兴趣的:(MySQL,sql,大数据,数据库,面试,mysql)