2016-08-24 15 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は、2014年8月10日2013年7月1日を通してのための2つの行を有します。私は間違いだと思って、その行の1つを削除しました。

これ以外は、日付範囲の「ギャップとアイランド」の問題を解決するための「タブビトサン法」の応用です。このトリックは、隣接する間隔の「グループ」(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

これは素晴らしいです!ありがとうございました! 2列の従業員Aについては、2つのWAGE_CDの間に違いがあることを示したいと考えました。テーブルに別のレベルの情報を追加することはできましたが、これ以上混乱させたくありませんでした。 ORA-01841:(full)year ...エラーが発生しました。 – krwoibnvts