안녕하세요.
database sarang net 에서 검색하니 좋은 쿼리가 있어 참조하여 수정 중 다소 비효율적인 쿼리로
나와서 혹시나 개선할 방법이 있는지 여쭈어 봅니다.
출력을 원하는 것은 아래 with문의 row 데이터에서
특정 일자에서 시작시간(sdt) ~ 종료시간(edt) 이 없는 시간대를 출력하는 것입니다.
아래 최종 쿼리로 결과는 제대로 나옵니다만, 비 효율적인 부분이 보여 좀더 효율적으로
개선할 방안이 있는지 해서 글을 올립니다.
(비효율은 아래와 같아 보입니다)
1. union all 로 마지막 시간대를 하는 부분 말고 한방 쿼리로 가능할까요?
2. 마지막 시간대 부분의 레코드 출력 부분이 중복되는 부분
혹시나 저와 같은 고민으로 해결하신 선배님들 계시면 조언 바라겠습니다.
감사합니다.
쿼리 개발은 아래와 같습니다.
1. 23:59 분 전까지의 시간 대의 로데이터 레코드가 있는 만큼 중복 발생 함.
with t as (
select to_date('201108011400', 'yyyy-mm-dd hh24:mi:ss') sdt
,to_date('201108011700', 'yyyy-mm-dd hh24:mi:ss') edt from dual
union all
select to_date('201108012000', 'yyyy-mm-dd hh24:mi:ss') sdt
,to_date('201108012259', 'yyyy-mm-dd hh24:mi:ss') edt from dual
)
select decode(from_dt
,null,to_char(trunc(to_dt,'dd') + 1/24/60,'yyyy-mm-dd hh24:mi:ss')
,to_char(from_dt, 'yyyy-mm-dd hh24:mi:ss')
) from_dt
,to_char(to_dt,'yyyy-mm-dd hh24:mi:ss') to_dt
from (
select max(edt)
over(order by sdt, edt
rows between unbounded preceding and 1 preceding
) + 1/24/60
as from_dt
,sdt - 1/24/60
as to_dt
from t
union all
select max(edt)
over(order by sdt, edt
rows between 1 preceding and 1 following
) + 1/24/60
as from_dt
,trunc(edt+1,'dd') - 1/24/60
as to_dt
from t
);
FROM_DT TO_DT
========== ===========
2011-08-01 00:01:00 2011-08-01 13:59:00
2011-08-01 17:01:00 2011-08-01 19:59:00
2011-08-01 23:00:00 2011-08-01 23:59:00 --- 중복
2011-08-01 23:00:00 2011-08-01 23:59:00 --- 중복
2. rownum = 1 추가.
select decode(from_dt
,null,to_char(trunc(to_dt,'dd') + 1/24/60,'yyyy-mm-dd hh24:mi:ss')
,to_char(from_dt, 'yyyy-mm-dd hh24:mi:ss')
) from_dt
,to_char(to_dt,'yyyy-mm-dd hh24:mi:ss') to_dt
from (
select max(edt)
over(order by sdt, edt
rows between unbounded preceding and 1 preceding
) + 1/24/60
as from_dt
,sdt - 1/24/60
as to_dt
from t
union all
select from_dt
,to_dt
from (
select max(edt)
over(order by sdt, edt
rows between 1 preceding and 1 following
) + 1/24/60
as from_dt
,trunc(edt+1,'dd') - 1/24/60
as to_dt
,rownum rn
from t
)
where rn = 1
);
FROM_DT TO_DT
========== ===========
2011-08-01 00:01:00 2011-08-01 13:59:00
2011-08-01 17:01:00 2011-08-01 19:59:00
2011-08-01 23:00:00 2011-08-01 23:59:00
|