2016-08-24 30 views
6

Oracle SQL newbie tại đây và áp phích lần đầu tiên.Phạm vi ngày kết hợp

Tôi nghĩ điều này sẽ đơn giản cho đến khi tôi nhận ra rằng tôi không thể tìm ra cách phân chia các bài tập trở lại.

Dưới đây là bảng phân công của tôi: 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 

Tôi đã cố gắng này dưới đây với kết quả bất ngờ.

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 

Kết quả không mong đợi, nhưng có ý nghĩa. Đây là nơi mà các bài tập trở lại không được phân tách bằng cách kết hợp với các bài tập trước đó.

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 

Và kết quả tôi muốn nhìn thấy nơi các ngày liền kề được kết hợp mỗi ID, vị trí, vị trí và TÌNH TRẠNG:

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 

Tôi hỏi một mùa hơn Oracle lập trình SQL và ông nói tôi chúng tôi có PLSQL, nhưng tôi nghĩ rằng phải có một cách để thực hiện công việc này thông qua SQL.

thử nghiệm thiết lập kịch bản:

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'); 

Trả lời

4

nhân viên A có hai hàng cho 2013/07/01 qua 2014/08/10; Tôi cho rằng đó là một sai lầm và tôi đã xóa một trong các hàng.

Ngoài ra, đây là một ứng dụng của "phương pháp tabibitosan" để giải quyết các vấn đề "khoảng trống và hải đảo" cho phạm vi ngày. Bí quyết là tạo ra các "nhóm" (gp) cho các khoảng liền kề.

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

Điều này thật tuyệt! Cảm ơn bạn! Đối với nhân viên A có hai hàng, tôi muốn cho thấy có sự khác biệt giữa WAGE_CD giữa hai hàng. Tôi có thể đã thêm một mức độ thông tin khác trong bảng, nhưng không muốn gây nhầm lẫn thêm nữa. Bây giờ, tôi chỉ cần tìm ra lỗi ORA-01841: (đầy đủ) năm ... mà tôi nhận được. – krwoibnvts

Các vấn đề liên quan