Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

달바라기

오라클에서 쿼리로 달력 만들기 본문

카테고리 없음

오라클에서 쿼리로 달력 만들기

착한악마 2024. 9. 3. 18:11

1.  connect by 절에 rownum 조건으로 해당 월의 마지막 일자 만큼 반복

2. rownum을 사용하여 해당월의 모든 일자 생성

SELECT TO_CHAR(MM + ROWNUM - 1, 'YYYYMMDD') DD
  FROM (SELECT TO_DATE(TO_CHAR(SYSDATE, 'YYYYMM'), 'YYYYMM') MM FROM DUAL)
CONNECT BY ROWNUM <= TO_CHAR(LAST_DAY(MM), 'dd')

 

 

 - 이후 달력형으로 만들기 위해 월일, 일, 요일구분, 년중 주차 값을 추가

SELECT TO_CHAR(MM + ROWNUM - 1, 'YYYYMMDD') ORDDD
     , TO_CHAR(MM + ROWNUM - 1, 'MMDD') MMDD
     , TO_CHAR(MM + ROWNUM - 1, 'dd') DAYNUM
     , TO_CHAR(MM + ROWNUM - 1, 'd') WEEKDAY
     -- 오라클 주의 시작은 월요일 부터. 일요일 부터 시작하기 위해 1을 더한다.
     , TO_CHAR(MM + ROWNUM, 'IW') WEEKNUM  
  FROM (SELECT TO_DATE(TO_CHAR(SYSDATE, 'YYYYMM'), 'YYYYMM') MM FROM DUAL)
 CONNECT BY ROWNUM <= TO_CHAR(LAST_DAY(MM), 'dd')

 

 

- 주차로 그룹하고 요일구분으로 각 일자 표시

SELECT MAX(DECODE(WEEKDAY, 1, DAYNUM)) SUN
     , MAX(DECODE(WEEKDAY, 2, DAYNUM)) MON
     , MAX(DECODE(WEEKDAY, 3, DAYNUM)) TUE
     , MAX(DECODE(WEEKDAY, 4, DAYNUM)) WED
     , MAX(DECODE(WEEKDAY, 5, DAYNUM)) THU
     , MAX(DECODE(WEEKDAY, 6, DAYNUM)) FRI
     , MAX(DECODE(WEEKDAY, 7, DAYNUM)) SAT
  FROM (SELECT TO_CHAR(MM + ROWNUM - 1, 'YYYYMMDD') ORDDD
             , TO_CHAR(MM + ROWNUM - 1, 'MMDD') MMDD
             , TO_CHAR(MM + ROWNUM - 1, 'dd') DAYNUM
             , TO_CHAR(MM + ROWNUM - 1, 'd') WEEKDAY
        -- 오라클 주의 시작은 월요일 부터. 일요일 부터 시작하기 위해 1을 더한다.
             , TO_CHAR(MM + ROWNUM, 'IW') WEEKNUM  
          FROM (SELECT TO_DATE(TO_CHAR(SYSDATE, 'YYYYMM'), 'YYYYMM') MM FROM DUAL)
        CONNECT BY ROWNUM <= TO_CHAR(LAST_DAY(MM), 'dd')) A
GROUP BY WEEKNUM
      -- 12월31일의 경우 주차를 계산할 때 1월1일을 보게되고 주차는 1이 되기 때문에 
      -- 해당 요일이 일요일이면 '99991231'로 처리 
ORDER BY DECODE(MIN(MMDD), '1231', '99991231', MIN(A.ORDDD))

 

주의! 주차를 일요일부터 적용하는 것 처럼 보이기 위해 1일 더해 계산. 즉 12월 31일은 다음해 1월 1일의 값.

주의! 주차 계산 규칙에 의해 1월의 첫주가 이전해 마지막 주차 값을 가지기도 하며,

          12월의 마지막 주가 다음해의 첫 주차 값을 가지기도 한다.

          해서 그주의 가장 작은 일자가 12월 31일 경우는 가장 큰 일자 값으로 해서 정렬하였음.

 

 

ps. 글작성후 https://m.blog.naver.com/cofla_qkqh/221120597766 에서 조금 더 간단한 방법 발견

SELECT MIN (DECODE (TO_CHAR (YM + rownum - 1, 'D'), '1', TO_CHAR (YM + rownum - 1, 'YYYY-MM-DD'))) SUN 
     , MIN (DECODE (TO_CHAR (YM + rownum - 1, 'D'), '2', TO_CHAR (YM + rownum - 1, 'YYYY-MM-DD'))) MON 
     , MIN (DECODE (TO_CHAR (YM + rownum - 1, 'D'), '3', TO_CHAR (YM + rownum - 1, 'YYYY-MM-DD'))) TUE 
     , MIN (DECODE (TO_CHAR (YM + rownum - 1, 'D'), '4', TO_CHAR (YM + rownum - 1, 'YYYY-MM-DD'))) WED 
     , MIN (DECODE (TO_CHAR (YM + rownum - 1, 'D'), '5', TO_CHAR (YM + rownum - 1, 'YYYY-MM-DD'))) THU 
     , MIN (DECODE (TO_CHAR (YM + rownum - 1, 'D'), '6', TO_CHAR (YM + rownum - 1, 'YYYY-MM-DD'))) FRI 
     , MIN (DECODE (TO_CHAR (YM + rownum - 1, 'D'), '7', TO_CHAR (YM + rownum - 1, 'YYYY-MM-DD'))) SAT 
 FROM (select to_date('202412','yyyymm') ym FROM DUAL) 
CONNECT BY rownum <= to_char(LAST_DAY (YM), 'DD')
GROUP BY TRUNC (YM + rownum, 'iw') 
ORDER BY min(rownum) ;

TRUNC (YM + rownum, 'iw') 을 사용하면 해당 주차의 가장 작은 일자를 가져옴.

min(rownum)를 사용하면 1월 초, 12월 말 주차의 문제가 해결됨