2016-08-24 86 views
6

Oracle SQL新手在这里和第一次张贴海报。合并日期范围

我认为这将是简单的,直到我意识到我无法弄清楚如何分割返回分配。

这里是我的作业表:ASGN

ID ST_DT  END_DT  POS LOCN STATUS WAGE_CD 
-- ---------- ---------- ----- ---- ------ ------- 
A 12-31-2006 08-16-2009 CLERK LAX 3  A 
A 08-17-2009 10-04-2009 CLERK LAX 0  Z 
A 10-05-2009 06-30-2010 OPR NYC 3  A 
A 07-01-2010 12-31-2010 OPR NYC 3  B 
A 01-01-2011 06-30-2012 OPR NYC 3  C 
A 07-01-2012 04-09-2013 OPR NYC 3  D 
A 04-10-2013 06-30-2013 CLERK LAX 3  A 
A 07-01-2013 08-10-2014 CLERK LAX 3  B 
A 07-01-2013 08-10-2014 CLERK LAX 3  C 
B 04-10-2013 05-31-2013 SUP LAX 3  A 
B 06-01-2013 06-30-2014 SUP LAX 0  Z 
B 07-01-2013 08-10-2014 SUP LAX 3  B 
B 08-11-2014 08-11-2014 CLERK NYC 3  A 
B 08-12-2014 01-11-2015 SUP LAX 3  A 
B 01-12-2015 02-10-2016 SUP LAX 3  B 
B 02-11-2016 08-12-2016 OPER SFO 3  A 
B 02-11-2016 08-12-2016 OPER SFO 3  B 

我已经有意想不到的效果试过下面这样。

SELECT * 
FROM (
    SELECT ID 
     ,MIN(ST_DT) ST_DT 
     ,MAX(END_DT) END_DT 
     ,POS 
     ,LOCN 
     ,STATUS 
    FROM ASGN 
    GROUP BY ID, LOCN, POS, STATUS 
) SUBQRY 
ORDER BY ID, ST_DT 

意外的结果,但有道理。这是返回分配不与以前的分配相结合的地方。

ID ST_DT  END_DT  POS LOCN STATUS 
-- ---------- ---------- ----- ---- ------ 
A 12-31-2006 08-10-2014 CLERK LAX 3 
A 08-17-2009 10-04-2009 CLERK LAX 0 
A 10-05-2009 04-09-2010 OPR NYC 3 
B 04-10-2013 02-10-2015 SUP LAX 3 
B 06-01-2013 06-30-2014 SUP LAX 0 
B 08-11-2014 08-11-2014 CLERK NYC 3 
B 02-11-2016 08-12-2016 OPER SFO 3 

而且看到我想结果在相邻日期每ID,位置,位置相结合,STATUS:

ID ST_DT  END_DT  POS LOCN STATUS 
-- ---------- ---------- ----- ---- ------ 
A 12-31-2006 08-16-2009 CLERK LAX 3 
A 08-17-2009 10-04-2009 CLERK LAX 0 
A 10-05-2009 04-09-2010 OPR NYC 3 
A 04-10-2013 08-10-2014 CLERK LAX 3 
B 04-10-2013 05-31-2013 SUP LAX 3 
B 06-01-2013 06-30-2014 SUP LAX 0 
B 07-01-2013 08-10-2014 SUP LAX 3 
B 08-11-2014 08-11-2014 CLERK NYC 3 
B 08-12-2014 02-10-2015 SUP LAX 3 
B 02-11-2016 08-12-2016 OPER SFO 3 

我问了一个多赛季的Oracle SQL程序员,他说我我们需要PLSQL,但我认为必须有一种方法可以通过SQL来完成这项工作。

测试设置脚本:

create table asgn 
(id varchar2(10) 
,st_dt date 
,end_dt date 
,pos varchar2(10) 
,locn varchar2(10) 
,status number 
,wage_cd varchar2(10)); 

insert into asgn values('A',to_date('12-31-2006','mm-dd-yyyy'),to_date('08-16-2009','mm-dd-yyyy'),'CLERK','LAX',3,'A'); 
insert into asgn values('A',to_date('08-17-2009','mm-dd-yyyy'),to_date('10-04-2009','mm-dd-yyyy'),'CLERK','LAX',0,'Z'); 
insert into asgn values('A',to_date('10-05-2009','mm-dd-yyyy'),to_date('06-30-2010','mm-dd-yyyy'),'OPR','NYC',3,'A'); 
insert into asgn values('A',to_date('07-01-2010','mm-dd-yyyy'),to_date('12-31-2010','mm-dd-yyyy'),'OPR','NYC',3,'B'); 
insert into asgn values('A',to_date('01-01-2011','mm-dd-yyyy'),to_date('06-30-2012','mm-dd-yyyy'),'OPR','NYC',3,'C'); 
insert into asgn values('A',to_date('07-01-2012','mm-dd-yyyy'),to_date('04-09-2013','mm-dd-yyyy'),'OPR','NYC',3,'D'); 
insert into asgn values('A',to_date('04-10-2013','mm-dd-yyyy'),to_date('06-30-2013','mm-dd-yyyy'),'CLERK','LAX',3,'A'); 
insert into asgn values('A',to_date('07-01-2013','mm-dd-yyyy'),to_date('08-10-2014','mm-dd-yyyy'),'CLERK','LAX',3,'B'); 
insert into asgn values('A',to_date('07-01-2013','mm-dd-yyyy'),to_date('08-10-2014','mm-dd-yyyy'),'CLERK','LAX',3,'C'); 
insert into asgn values('B',to_date('04-10-2013','mm-dd-yyyy'),to_date('05-31-2013','mm-dd-yyyy'),'SUP','LAX',3,'A'); 
insert into asgn values('B',to_date('06-01-2013','mm-dd-yyyy'),to_date('06-30-2014','mm-dd-yyyy'),'SUP','LAX',0,'Z'); 
insert into asgn values('B',to_date('07-01-2013','mm-dd-yyyy'),to_date('08-10-2014','mm-dd-yyyy'),'SUP','LAX',3,'B'); 
insert into asgn values('B',to_date('08-11-2014','mm-dd-yyyy'),to_date('08-11-2014','mm-dd-yyyy'),'CLERK','NYC',3,'A'); 
insert into asgn values('B',to_date('08-12-2014','mm-dd-yyyy'),to_date('01-11-2015','mm-dd-yyyy'),'SUP','LAX',3,'A'); 
insert into asgn values('B',to_date('01-12-2015','mm-dd-yyyy'),to_date('02-10-2016','mm-dd-yyyy'),'SUP','LAX',3,'B'); 
insert into asgn values('B',to_date('02-11-2016','mm-dd-yyyy'),to_date('08-12-2016','mm-dd-yyyy'),'OPER','SFO',3,'A'); 
insert into asgn values('B',to_date('02-11-2016','mm-dd-yyyy'),to_date('08-12-2016','mm-dd-yyyy'),'OPER','SFO',3,'B'); 

回答

4

员工A有两行对2013年7月1日至2014年8月10日;我认为这是一个错误,我删除了其中的一行。

除此之外,这是“tabibitosan方法”用于解决日期范围的“间隙和岛屿”问题的应用。诀窍在于创建相邻区间的“组”(gp)。

with 
    prep (id, st_dt, end_dt, gp, pos, locn, status) as (
     select id, st_dt, end_dt, 
       end_dt - sum(end_dt - st_dt + 1) over (partition by id, pos, locn, status 
                 order by st_dt), 
       pos, locn, status 
     from asgn 
    ) 
select id, min(st_dt) as st_dt, max(end_dt) as end_dt, pos, locn, status 
from prep 
group by id, gp, pos, locn, status 
order by id, st_dt 
; 



ID   ST_DT  END_DT  POS  LOCN   STATUS 
---------- ---------- ---------- ---------- ---------- ---------- 
A   12-31-2006 08-16-2009 CLERK  LAX     3 
A   08-17-2009 10-04-2009 CLERK  LAX     0 
A   10-05-2009 04-09-2013 OPR  NYC     3 
A   04-10-2013 08-10-2014 CLERK  LAX     3 
B   04-10-2013 05-31-2013 SUP  LAX     3 
B   06-01-2013 06-30-2014 SUP  LAX     0 
B   07-01-2013 08-10-2014 SUP  LAX     3 
B   08-11-2014 08-11-2014 CLERK  NYC     3 
B   08-12-2014 02-10-2016 SUP  LAX     3 
B   02-11-2016 08-12-2016 OPER  SFO     3 

10 rows selected 
+0

这太好了!谢谢! 对于两行的员工A,我想表明两者之间的WAGE_CD存在差异。我可以在表中添加另一个级别的信息,但不想进一步混淆。 现在,我只需要弄清楚我收到的ORA-01841:(full)year ...错误。 – krwoibnvts