我有一个表,其中包含代表'person-career'
的多个时间段,在同一表中,我所有与同一个人(即holidays, illnesses
...相关的中断)。
该表中使用的订单是(按codeMission的顺序,然后是year,然后是工作类型,然后是Holidays期)
Date begin Date end Type codeMission year name
---------- --------------------------------------------
2001-01-01 2001-12-31 Working Tx100 2001 James
2001-05-01 2001-05-12 holidays Tx100 2001 James
我想按假期划分工作时间
Date begin Date end Type codeMission year name
---------- -----------------------------------------
2001-01-01 2001-04-30 Working Tx100 2001 James
2001-05-01 2001-05-12 holiday Tx100 2001 James
2001-05-13 2001-12-31 Working Tx100 2001 James
有一般的方法吗?如您所知,假期/疾病时间有时可以在某些时间之前和之后。
问题1:如何获得所有列的这种格式?我想在这里提一个具体的内容, 问题2:何时将假期定义为两年。例如:
Date begin Date end Type codeMission year name
---------- --------------------------------------------
2001-01-01 2001-12-31 Working Tx100 2001 James
2001-10-11 2002-04-30 holidays Tx100 2001 James
2002-01-01 2001-12-31 Working Tx100 2002 James
在这里我们将收到多个问题!分期不正确! 你怎么了?
答案 0 :(得分:4)
这很复杂。这个想法是“取消透视”日期并跟踪type
在每天进出的情况。然后,您可以使用累积总和来跟踪实际类型。
所以:
with t as (
select date '2001-01-01' as sdate, date '2001-12-31' as edate, 'Working' as type from dual union all
select date '2001-05-01' as sdate, date '2001-05-12' as edate, 'holidays' from dual
),
d as (
select sdate as dte, type, 1 as flag from t union all
select edate + 1, type, -1 as flag from t
)
select d.dte, lead(dte) over (order by dte) - 1 as enddte,
(case when flag = -1 then lag(type) over (partition by grp order by dte) else type end) as type
from (select d.*, sum(flag) over (order by dte) as grp
from d
) d
order by dte;
Here是db <>小提琴。
编辑:
Here是改进的版本:
with t as (
select date '2001-01-01' as sdate, date '2001-12-31' as edate, 'Working' as type from dual union all
select date '2001-05-01' as sdate, date '2001-05-12' as edate, 'holidays' from dual union all
select date '2001-07-01' as sdate, date '2001-08-12' as edate, 'holidays' from dual
),
d as (
select sdate as dte from t union all
select edate + 1 from t
)
select d.dte, d.enddte,
(select max(t2.type) keep (dense_rank first order by t2.sdate desc)
from t t2
where t2.sdate <= d.dte and t2.edate >= d.enddte
) as type
from (select d.*, lead(dte) over (order by dte) - 1 as enddte
from d
) d
where dte <= enddte
order by d.dte
此方法仅获取各个期间(通过分解原始期间)。然后,对于每个时间段,它会找到在该时间段内有效的type
。那是涵盖整个时期的最新记录。
请注意,由于日期是“相邻的”,因此不会部分覆盖各个期间。