지난번 귀한답변 주셨는데 실제 데이터패턴은 좀 다양한 상황이라서 다시금 고수님들의 자문좀 구해보겠습니다.
SELECT 1 work_id, 'start' gbn, to_date('2014-01-02','YYYY-MM-DD') work_dt FROM dual UNION ALL
SELECT 1 work_id, 'end' gbn, to_date('2014-01-03','YYYY-MM-DD') work_dt FROM dual UNION ALL
SELECT 20 work_id, 'start' gbn, to_date('2014-01-05','YYYY-MM-DD') work_dt FROM dual UNION ALL
SELECT 21 work_id, 'start' gbn, to_date('2014-01-09','YYYY-MM-DD') work_dt FROM dual UNION ALL
SELECT 30 work_id, 'start' gbn, to_date('2014-01-15','YYYY-MM-DD') work_dt FROM dual UNION ALL
SELECT 30 work_id, 'start' gbn, to_date('2014-01-16','YYYY-MM-DD') work_dt FROM dual UNION ALL
SELECT 30 work_id, 'end' gbn, to_date('2014-01-17','YYYY-MM-DD') work_dt FROM dual
로직은 시작일과 종료일별 일자간격을 구하는것인데
문제는 위데이이터에서 work_id가 30이고 start가 연달아 이어질때 첫행만 취해야하는것입니다.
시작일기준 : gbn의 값이 'start'이고
종료일기준1 :이전행의 work_id동일하고 gbn값이 'end'
종료일기준2 :이전행의 work_id가 다르고 gbn값이 'start'
원하는 결과는 아래와 같습니다.
start_dt *********** end_dt *********** term 2014-01-02 ******* 2014-01-03 ******* 1
2014-01-05 ******* 2014-01-09 ******* 4
2014-01-09 ******* 2014-01-15 ******* 6
2014-01-15 ******* 2014-01-17 ******* 2
자체 해결했을때 서브쿼리를 두번사용하다보니 성능에 심각한 문제가 있어서 자문을 다시 구해보겠습니다.
아래는 자체 해결한 방식입니다.
with t as (…)
select work_id, start_dt, end_dt, gbn
From
(
Select work_id, gbn, work_dt start_dt,
Lead(work_dt) over (order by work_dt) end_dt
From
(
Select work_id, work_dt, gbn
From
(
Select work_id, work_dt, gbn,
Lag(work_id,1,99) over(order by work_dt) pre_work_id, lag(gbn,1,'x') over(order by work_dt) pre_gbn
From t
)
Where work_id!=pre_work_id or ( work_id=pre_work_id and gbn!=pre_gbn)
)
)
Where gbn='start' |