by 마카히로 [Oracle 기초] oracle 날짜 두사이 불러오기 [2023.01.25 19:13:20]
안녕하세요
시작일과 종료일이 있는 테이블에서 시작일과 종료일 사이 날짜를 행으로 불러오는 쿼리를 찾아서 적용하였는데 잘 안되서 질문드립니다!
시작일 | 종료일 | |
1 | 2023-01-01 | 2023-01-05 |
2 | 2023-01-02 | 2023-01-04 |
~ | ~ | ~ |
n번째 | 2023-01-25 | 2023-01-25 |
1 2 3 4 5 6 7 | WITH TEST1 AS (생략) SELECT TO_CHAR(TO_DATE(시작일) + LEVEL -1, 'YYYY-MM-DD' ) AS DATE FROM TEST1 CONNECT BY LEVEL <= (TO_DATE(종료일, 'YYYYMMDD' ) - TO_DATE(시작일, 'YYYYMMDD' ) +1) |
이렇게 짤 경우, 시작일과 종료일 사이에 날짜들만 쭉 나와야하는데
생각보다 너무 많은 데이터가 나옵니다 ㅜㅜ
데이터가 왜 많이나오는지 알기 위해 CONNECT BY LEVEL <= 2 를 넣었더니
N* (N+1) 개 데이터가 나오더라구요 ㅜㅜ
고수님들 도움 간곡히 부탁드립니다!
CONNECT BY LEVEL <= n 형태의 행복제 방식은
dual 처럼 1행의 자료에만 적용하는 방법입니다.
여러행의 자료에 직접 적용하면 기하급수로 복제가 됩니다.
http://gurubee.net/article/55635
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | WITH test1 AS ( SELECT 1 no , '2023-01-01' sdt, '2023-01-05' edt FROM dual UNION ALL SELECT 2, '2023-01-02' , '2023-01-04' FROM dual UNION ALL SELECT 3, '2023-01-25' , '2023-01-25' FROM dual ) SELECT no , TO_CHAR(sdt + lv - 1, 'yyyy-mm-dd' ) dt FROM ( SELECT no , TO_DATE(sdt, 'yyyy-mm-dd' ) sdt , TO_DATE(edt, 'yyyy-mm-dd' ) edt FROM test1 ) , ( SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 99) WHERE lv <= edt - sdt + 1 ORDER BY no , dt ; |
제가 어려웠던 부분 공유드리고자합니다^^;;
sdt 2023-01-01 ,edt 2023-01-03 일때
조정값1 select : sdt + lv
조정값2: where : lv <=edt -sdt
1. 시작일,종료일을 포함하고 싶을 때
조정값1:sdt + lv -1
조정값2:lv<= edt-sdt +1
>결과: 1/1,1/2,1/3일 출력
2. 시작일 제외, 종료일을 포함하고 싶을 때
조정값1: sdt + lv
조정값2: edt-sdt
>결과: 1/2,1/3 일 출력
3.시작일 포함, 종료일 제외하고 싶을 때
조정값1: sdt + lv-1
조정값2: edt-sdt
>결과: 1/1,1/2 일 출력
1 2 3 4 5 6 7 8 9 | WITH TMP ( NO , SDT, EDT) AS ( SELECT 1, '2023-01-01' , '2023-01-05' FROM DUAL UNION ALL SELECT 2, '2023-01-02' , '2023-01-04' FROM DUAL UNION ALL SELECT 3, '2023-01-25' , '2023-01-25' FROM DUAL ) SELECT DISTINCT NO , TO_CHAR(TO_DATE(SDT, 'YYYY-MM-DD' ) + LEVEL -1, 'YYYY-MM-DD' ) AS DT FROM TMP CONNECT BY LEVEL <= (TO_DATE(EDT, 'YYYY-MM-DD' ) - TO_DATE(SDT, 'YYYY-MM-DD' ) +1) ORDER BY NO , DT; |
이렇게 하면 되긴 하는데..마농님 말씀 처럼 기하급수로 복제가 되서 Row가 많을시에는 어떻게 될지 모르겠네요..
그룹별 (NO별) CONNECT BY 하는 방법도 있을것 같은데....@.@