아래와 같은 결과를 얻으려고 CONNECT BY를 생각해 보고 시도 하다가
답을 얻지 못해서 조언을 받고자 올려봅니다.
CONNECT_BY_ISLEAF를 이용해보려도 시도 해보고 있구요...
REGEXP_SUBSTR를 사용하고 나서 CONNECT BY를 해서인지....토드에서 오류도 나네요 ㅠㅠ
안쪽 쿼리만으로는 잘 되는데...
SELECT PROCID, EDU_SEQ ,MAX(CONNECT_BY_ISLEAF * PROCID) OVER () AS CHANGE_PROCID ,MAX(CONNECT_BY_ISLEAF * EDU_SEQ) OVER () AS CHANGE_EDU_SEQ ,EDU_CHANGE_FLAG_TYPE AS CHANGE_EDU_CHANGE_FLAG_TYPE ,EDU_GBN, EDU_PLANTYPE ,EDU_ID_LIST, EDU_NAME_LIST, EDU_DEPTNAME ,EDU_ETC_LIST, EDU_ETC_CNT ,EDU_TITLE, EDU_ORGAN, EDU_PLACE, EDU_TUITION_FEE, EDU_ETC_FEE, EDU_REFUND_FLAG ,EDU_YEAR, EDU_PERIOD_TYPE, EDU_PERIOD_LIST, EDU_PERIOD_ETC, EDU_START_DATE, EDU_END_DATE, EDU_TIME ,EDU_TYPE, EDU_CONTENTS_ETC, SPV_GBN ,EDU_FLAG, EDU_CHANGE_FLAG_TYPE FROM ( SELECT EL.PROCID, EL.EDU_SEQ, EDU_BEFORE_PROCID, EDU_BEFORE_SEQ, EL.EDU_GBN, EL.EDU_PLANTYPE, NVL(LTRIM(REGEXP_SUBSTR(EDU_ID_LIST,'[^,]+',1,LV)), 'NOT') EDU_ID_LIST, LTRIM(REGEXP_SUBSTR(EDU_NAME_LIST,'[^,]+',1,LV)) EDU_NAME_LIST, LTRIM(REGEXP_SUBSTR(EDU_DEPTNAME,'[^,]+',1,LV)) EDU_DEPTNAME, EL.EDU_ETC_LIST, EL.EDU_ETC_CNT, EL.EDU_TITLE, EL.EDU_ORGAN, EL.EDU_PLACE, EDU_TUITION_FEE, EDU_ETC_FEE, EDU_REFUND_FLAG, EL.EDU_YEAR, EDU_PERIOD_TYPE, NVL(EDU_PERIOD_LIST, 'NOT') EDU_PERIOD_LIST, EDU_PERIOD_ETC, EDU_START_DATE, EDU_END_DATE, EDU_TIME, EL.EDU_TYPE, EL.EDU_CONTENTS_ETC, EL.SPV_GBN, EDU_FLAG, EDU_CHANGE_FLAG_TYPE FROM WF_EDUCATION_LIST EL, (SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL <= 100) LE WHERE 1=1 AND EDU_GBN = 'OUT' AND EDU_NAME_LIST LIKE '%이순신%' AND REGEXP_SUBSTR(EDU_ID_LIST,'[^,]+',1,LV) IS NOT NULL )A WHERE 1=1 START WITH EDU_BEFORE_SEQ IS NULL CONNECT BY PRIOR EDU_SEQ = EDU_BEFORE_SEQ
ID가 1번인 업무 이외에는 변경사항이 없어서 그대로 조회되어야 하지만
1번은 두번에 걸쳐서 변경사항이 생겨서 최초 값과 최종변경값을 얻어내려는 상태입니다.
원본 데이터
ID | SEQ | BEFORE_ID | BEFORE_SEQ | CHANGE | USING | TITLE | 원인 |
1 | 11 | NOT | 업무1 | ||||
1 | 12 | USE | 업무2 | ||||
2 | 13 | USE | 업무3 | ||||
3 | 14 | USE | 업무4 | ||||
4 | 15 | 1 | 11 | CHANGE | NOT | 업무1 | 바쁨 |
5 | 16 | USE | 업무5 | ||||
6 | 17 | 4 | 15 | CHANGE | USE | 업무1 | 또 바쁨 |
조회 결과
ID | SEQ | CHANGE_ID | CHANGE_SEQ | CHANGE_TYPE | USING | TITLE | 원인 |
1 | 11 | 6 | 17 | CHANGE | USE | 업무1 | 또바쁨 |
1 | 12 | USE | 업무2 | ||||
2 | 13 | USE | 업무3 | ||||
3 | 14 | USE | 업무4 | ||||
5 | 16 | USE | 업무5 |
WITH T AS ( SELECT 1 ID, 11 SEQ, NULL BEFORE_ID, NULL BEFORE_SEQ, NULL CHANGE, 'NOT' USING, '업무1' TITLE, NULL REASON FROM DUAL UNION ALL SELECT 1 ID, 12 SEQ, NULL BEFORE_ID, NULL BEFORE_SEQ, NULL CHANGE, 'USE' USING, '업무2' TITLE, NULL REASON FROM DUAL UNION ALL SELECT 2 ID, 13 SEQ, NULL BEFORE_ID, NULL BEFORE_SEQ, NULL CHANGE, 'USE' USING, '업무3' TITLE, NULL REASON FROM DUAL UNION ALL SELECT 3 ID, 14 SEQ, NULL BEFORE_ID, NULL BEFORE_SEQ, NULL CHANGE, 'USE' USING, '업무4' TITLE, NULL REASON FROM DUAL UNION ALL SELECT 4 ID, 15 SEQ, 1 BEFORE_ID, 11 BEFORE_SEQ, 'CHANGE' CHANGE, 'NOT' USING, '업무1' TITLE, '바쁨' REASON FROM DUAL UNION ALL SELECT 5 ID, 16 SEQ, NULL BEFORE_ID, NULL BEFORE_SEQ, NULL CHANGE, 'USE' USING, '업무5' TITLE, NULL REASON FROM DUAL UNION ALL SELECT 6 ID, 17 SEQ, 4 BEFORE_ID, 15 BEFORE_SEQ, 'CHANGE' CHANGE, 'USE' USING, '업무1' TITLE, '또 바쁨' REASON FROM DUAL ) SELECT ID, SEQ , DECODE(BEFORE_ID, ID, NULL, BEFORE_ID) BEFORE_ID , DECODE(BEFORE_SEQ, SEQ, NULL, BEFORE_SEQ) BEFORE_SEQ , CHANGE, USING, TITLE, REASON FROM (SELECT ID, SEQ , MAX(BEFORE_ID) OVER(PARTITION BY ID, SEQ) BEFORE_ID , MAX(BEFORE_SEQ) OVER(PARTITION BY ID, SEQ) BEFORE_SEQ , CHANGE, USING, TITLE, REASON , ROW_NUMBER() OVER(PARTITION BY ID, SEQ ORDER BY BEFORE_SEQ DESC) RN FROM (SELECT CONNECT_BY_ROOT ID ID , CONNECT_BY_ROOT SEQ SEQ , ID BEFORE_ID, SEQ BEFORE_SEQ , CHANGE, USING, TITLE, REASON FROM T START WITH BEFORE_ID IS NULL CONNECT BY BEFORE_ID = PRIOR ID AND BEFORE_SEQ = PRIOR SEQ )) WHERE RN = 1;
SELECT CONNECT_BY_ROOT(procid ) procid , CONNECT_BY_ROOT(edu_seq) edu_seq , DECODE(LEVEL, 1, null, procid ) change_procid , DECODE(LEVEL, 1, null, edu_seq) change_edu_seq , ... FROM (SELECT * FROM wf_education_list WHERE edu_gbn = 'OUT' AND edu_name_list LIKE '%이순신%' ) WHERE CONNECT_BY_ISLEAF = 1 START WITH edu_before_procid IS NULL AND edu_before_seq IS NULL CONNECT BY PRIOR procid = edu_before_procid AND PRIOR edu_seq = edu_before_seq ;
마농님 감사합니다. ^^
그런데 추가 질문이 있어요...
제가 적은 쿼리에서 FROM절에 있는 REGEXP_SUBSTR는 필수로 필요한데
토드에서 실행하면 REGEXP_SUBSTR 때문에 EOF에러가 나서 실행되다 말게 되는데 해결책이 있을까요
알려주신대로 하면 잘 되는데 REGEXP_SUBSTR까지 이용하면 같은 현상이라서요 ㅠㅠ
하나의 PROCID, EDU_SEQ에 해당하는 EDU_ID_LIST에는(0000004823,0000008557)
여러 사람이 존재하는데 각각을 개별 사용하게 됩니다.
그래서 PROCID, EDU_SEQ, EDU_ID가 기준값이 되거든요
ORA-03113: 통신 채널에 EOF 가 있습니다
프로세스 ID: 0
세션 ID: 430 일련 번호: 27575
connect by level 을 이용한 행복제 및 regexp_substr 은
계층 쿼리 전개 전에 수행하시면 안되고, 중복 발생으로 쿼리가 뻗을 수 있음
계층 전개 후에 수행하세요.
SELECT procid , edu_seq , change_procid , change_edu_seq , REGEXP_SUBSTR(edu_id_list, '[^,]+', 1, lv) edu_id , ... FROM (SELECT CONNECT_BY_ROOT(procid ) procid , CONNECT_BY_ROOT(edu_seq) edu_seq , DECODE(LEVEL, 1, null, procid ) change_procid , DECODE(LEVEL, 1, null, edu_seq) change_edu_seq , edu_id_list , ... FROM (SELECT * FROM wf_education_list WHERE edu_gbn = 'OUT' AND edu_name_list LIKE '%이순신%' ) WHERE CONNECT_BY_ISLEAF = 1 START WITH edu_before_procid IS NULL AND edu_before_seq IS NULL CONNECT BY PRIOR procid = edu_before_procid AND PRIOR edu_seq = edu_before_seq ) a , (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 99) b WHERE lv <= REGEXP_COUNT(edu_id_list, '[^,]+') ;