数据源:
操作日期 系统号 操作员A岗 操作员B岗
.............................
20200519 K 张三 李四
20200528 K 王五 张三
20200529 K 张三 李四
20200604 K 张三 王五
20200608 K 张三 李四
20200612 K 李四 张三
20200621 K 张三 李四
20200622 K 王五 张三
.............................
1.操作日期是没有规律的,可能一天用好几次,也可能一次不用。
2.操作员A岗和B岗人员是不固定的,可以是任何一个人。
3.任何一个操作员不能连续操作系统超过30天。
4.数据源中张三就超期了,(5月19日-6月22日)。如果把5月28日张三改成李四,则所有人没有超期。
select *
from (select t.操作员A岗,
t.连续操作开始日期,
t.连续操作结束日期,
连续操作结束日期 - 连续操作开始日期+1 as 连续工作时长,
rank() over(partition by 操作员A岗 order by 连续操作结束日期 - 连续操作开始日期 desc) rn
from (select a.操作员A岗,
b.操作日期 as 连续操作结束日期,
a.操作日期 as 连续操作开始日期
from (select t.*,
row_number() over(partition by 操作员A岗 order by 操作日期) rn
from (SELECT *
FROM (select 操作员A岗, 操作日期
from TEST
UNION
select 操作员B岗, 操作日期
from TEST)
group by 操作日期, 操作员A岗) t) a,
(select t.*,
row_number() over(partition by 操作员A岗 order by 操作日期) rn
from (SELECT *
FROM (select 操作员A岗, 操作日期
from TEST
UNION
select 操作员B岗, 操作日期
from TEST)
group by 操作日期, 操作员A岗) t) b
where a.操作员A岗 = b.操作员A岗
and a.操作日期 <= b.操作日期
and b.操作日期 - a.操作日期 = b.rn - a.rn) t)
where rn = 1
and 连续工作时长 >= 30
以日期为范围遍及,出现就计数,并跳过此日,开始下一日的检索,最后看有没有达到30的人。
可以,以操作员A岗作为主键连自己操作员B岗查询,判断是否存在时间差>30天。
检索出来,再手动更换么?
同楼上说的,这种最好用后端语言做
如果手动修改的话
select operator,date from table a where (select count(0) from table b where b.date >= a.date and b.date < a.date + 30 and (b.operatorA = operator or b.operatorB = operator)) >= 30
这样应该能查到,效率应该不高
with a as (
select '20200519' as rq , 'K' as x, '张三' as n1, '李四' as n2
union all select
'20200528', ' K', '王五', '张三'
union all select
'20200529' , 'K', '张三', '李四'
union all select
'20200604' , 'K', '张三', '王五'
union all select
'20200608' , 'K', '张三', '李四'
union all select
'20200612' , 'K', '李四', '张三'
union all select
'20200621' , 'K', '张三', '李四'
union all select
'20200622' , 'K', '王五', '张三' )
select c.n1,c.mrq,c.xrq from (
select b.n1,MIN(b.rq) AS mrq,MAX(b.rq) AS xrq from (
select rq,x,n1 from a
union all
select rq,x,n2 from a
) b
group by b.n1
) c
where DATEDIFF(day,CAST(c.mrq as datetime),CAST(c.xrq as datetime)) > 30