오라클 달력 콩 볶아 먹듯이 쉽게만들기

오라클을 아무것도 몰랐을때 오라클로 달력을 만드는것을 보고 깜짝놀란 기억이 납니다. 지금도 신기하기만한데 그때는 신선한 충격이었죠. 제 사수가 되시는 분은 오라클로 문서를 만드시더군요. 출력용으로...

 

아래 내용을 보시기 전에 이해를 돕고자 다른 포스팅을 참고해주세요. LEVEL에 대해서 잘모르시면 내용이 어려울 수도 있습니다.

 

 

달력은 알고보면 정말 쉽게 만들어집니다. 구조를 파악하지 못해서 어려운것이죠. 그럼 세세하게 하나씩 파헤쳐 보겠습니다.

 

조회되는 화면부터 보시죠.

 

 

 

기준이 되는 월이 있어야 되며 기준월에서 모든게 정해집니다.필요한조건은 아래와 같습니다.

 

1.해당되는 달의 1일부터 마지막까지의 날짜
2.날에 해당되는 첫번째 주

 

이렇게만 정리가 되면 달력을 만들어 볼수 있으니 위의 조건부터 만들어보겠습니다.

 

기준 월은 아래와 같이 만들니다.

 

SELECT TO_DATE(TO_CHAR(SYSDATE,'yyyymm'),'YYYYMM') AS BASE_MON
                  FROM dual

 


물론 SYSDATE가 아니라 다른 방법으로 치환해도 되겠습니다.
TO_CHAR(SYSDATE,'yyyymm') 부분은 원하시는 월로 바꿔주세요. 예) 201501

 

이제 LEVEL을 이용하여 한달의 목록을 뽑을건데, 전주에 해당되는 날짜를 같이 생성할겁니다. 여기에서 TRUC(날짜,'d') 명령어를 쓸건데 해당명령어는 해당되는 날짜의 해당주일 첫날짜를 반환합니다.

       

 

SELECT base_mon + LEVEL -1 AS days
                ,(TRUNC(base_mon+ LEVEL -1,'d') - TRUNC(TRUNC(base_mon + LEVEL -1,'y'),'d'))/7 +1 AS WEEK_GRP
          FROM (
                SELECT TO_DATE(TO_CHAR(SYSDATE,'yyyymm'),'YYYYMM') AS BASE_MON
                  FROM dual
               )
connect BY base_mon + LEVEL -1 <= LAST_DAY(base_mon)

 

결과

 

 

 


결과를 보시면 날짜와 해당주의 목록이 나열되었습니다. 마지막으로 그룹함수를 사용해서 정리만 해주면 달력이 되겠네요.

 

마지막으로 확인해야될구문은 TO_CHAR(days,'d'), TO_CHAR(days,'fmdd') 입니다.

TO_CHAR(days,'d') 는 해당주의 순번을 리턴하고, TO_CHAR(days,'fmdd')는 날짜를 리턴합니다.

 

2015-07-01 날짜는 해당주에서 4번째에 수요일에 위치해 있네요. DECODE와 그룹화함수 MIN을 이용해서 탈력 컬럼을 만들었습니다.

 

SELECT MIN(DECODE(TO_CHAR(days,'d'),1,TO_CHAR(days,'fmdd'))) 일
      ,MIN(DECODE(TO_CHAR(days,'d'),2,TO_CHAR(days,'fmdd'))) 월
      ,MIN(DECODE(TO_CHAR(days,'d'),3,TO_CHAR(days,'fmdd'))) 화
      ,MIN(DECODE(TO_CHAR(days,'d'),4,TO_CHAR(days,'fmdd'))) 수
      ,MIN(DECODE(TO_CHAR(days,'d'),5,TO_CHAR(days,'fmdd'))) 목
      ,MIN(DECODE(TO_CHAR(days,'d'),6,TO_CHAR(days,'fmdd'))) 금
      ,MIN(DECODE(TO_CHAR(days,'d'),7,TO_CHAR(days,'fmdd'))) 토
  FROM (
        SELECT base_mon + LEVEL -1 AS days
                ,(TRUNC(base_mon+ LEVEL -1,'d') - TRUNC(TRUNC(base_mon + LEVEL -1,'y'),'d'))/7 +1 AS WEEK_GRP
          FROM (
                SELECT TO_DATE(TO_CHAR(SYSDATE,'yyyymm'),'YYYYMM') AS BASE_MON
                  FROM dual
               )
connect BY base_mon + LEVEL -1 <= LAST_DAY(base_mon))
GROUP BY week_grp

 

위의 내용대로 그대로 진행하셨다면 달력만들기는 어렵지 않을꺼라 생각됩니다. 내용이 어려우시다면 차근차근 한문장씩 따라가면서 이해하시기 바랍니다.

예제 다운로드 :calendar.txt