본문 바로가기

Job/Oracle

[Oracle Sql] 주차 구하기 월/주/요일

SELECT CAL_DATE
     , YEAR_NO||WEEK_NO AS MS_YEAR_WEEK
     , MS_START_DATE
     , MS_END_DATE
     , YEAR_NO||MONTH_NO AS MS_MONTH
     , YEAR_NO
     , WEEK_DAY
     , START7_WEEK
     , SM_WEEK_1JAN
     , MS_WEEK_1JAN
  FROM (
        SELECT DT
             , TO_CHAR(DT,'YYYYMMDD') AS CAL_DATE
             , TO_CHAR(TRUNC(DT,'IW'),'YYYYMMDD') AS MS_START_DATE
             , TO_CHAR(TRUNC(DT,'IW')+7,'YYYYMMDD') AS MS_END_DATE
             , TO_CHAR(DT, 'DY') AS WEEK_DAY
             , TO_CHAR(DT, 'WW') AS START7_WEEK
             , LPAD(TRUNC((TRUNC(DT)-TRUNC(TRUNC(DT,'YY'),'D'))/7)+1,2,'0') AS SM_WEEK_1JAN
             , LPAD(TRUNC((TRUNC(DT)-TRUNC(TRUNC(DT,'YY'),'IW'))/7)+1,2,'0') AS MS_WEEK_1JAN
             , CASE WHEN LAST_DAY(DT) - NEXT_DAY((LAST_DAY(DT)-7),2) + 1 < 4           -- 월 마지막 주의 날수가 4일 미만이면서
                     AND DT <= LAST_DAY(DT) AND DT >= NEXT_DAY((LAST_DAY(DT)-7),2)   -- 해당일이 월 마지막 주의 일자에 포함되면
                    THEN TO_CHAR(ADD_MONTHS(DT,1),'YYYY')     -- 차월의 월이 속한 년도를 취하고
                    WHEN TO_NUMBER(TO_CHAR(NEXT_DAY((TRUNC(DT,'MM')-1),1),'DD')) < 4 -- 월 첫주의 날수가 4일 미만이면서
                     AND DT <= NEXT_DAY((TRUNC(DT,'MM')-1),1)   -- 해당일이 월 첫 주의 일자에 포함되면
                    THEN TO_CHAR(ADD_MONTHS(DT,-1),'YYYY')   -- 전월의 월이 속한 년도를 취하고
                    ELSE TO_CHAR(DT,'YYYY')                                       -- 그외는 당월의 월이 속한 년도를 취함.
                END AS YEAR_NO
             , CASE WHEN LAST_DAY(DT) - NEXT_DAY((LAST_DAY(DT)-7),2) + 1 < 4    -- 월 마지막 주의 날수가 4일 미만이면서
                     AND DT <= LAST_DAY(DT) AND DT >= NEXT_DAY((LAST_DAY(DT)-7),2)   -- 해당일이 월 마지막 주의 일자에 포함되면
                    THEN TO_CHAR(ADD_MONTHS(DT,1),'MM')       -- 차월의 월을 취하고
                    WHEN TO_NUMBER(TO_CHAR(NEXT_DAY((TRUNC(DT,'MM')-1),1),'DD')) < 4 -- 월 첫주의 날수가 4일 미만이면서
                     AND DT <= NEXT_DAY((TRUNC(DT,'MM')-1),1)    -- 해당일이 월 첫 주의 일자에 포함되면
                    THEN TO_CHAR(ADD_MONTHS(DT,-1),'MM')       -- 전월의 월을 취하고
                    ELSE TO_CHAR(DT,'MM')                                            -- 그 외는 당월의 월을 취함.
                END AS MONTH_NO
             , CASE WHEN LAST_DAY(DT) - NEXT_DAY((LAST_DAY(DT)-7),2) + 1 < 4         -- 월 마지막 주의 날수가 4일 미만이면서
                     AND DT <= LAST_DAY(DT) AND DT >= NEXT_DAY((LAST_DAY(DT)-7),2)   -- 해당일이 월 마지막 주의 일자에 포함되면
                    THEN TO_CHAR(DT, 'IW')                                           -- 차월의 월이 속한 주차를 취하고
                    WHEN TO_NUMBER(TO_CHAR(NEXT_DAY((TRUNC(DT,'MM')-1),1),'DD')) < 4 -- 월 첫주의 날수가 4일 미만이면서
                     AND DT <= NEXT_DAY((TRUNC(DT,'MM')-1),1)    -- 해당일이 월 첫 주의 일자에 포함되면
                    THEN TO_CHAR(DT, 'IW')                                           -- 전월의 월이 속한 주차를 취하고
                    ELSE TO_CHAR(DT, 'IW')                                            -- 그외는 당월의 월이 속한 주차를 취함.
                END AS WEEK_NO
          FROM (
                SELECT TRUNC(StartDT,'YY')+LEVEL-1 AS DT
                  FROM (SELECT TO_DATE('2006/01/01','YYYY/MM/DD') AS StartDT FROM DUAL)
               CONNECT BY LEVEL <= 365 * 10 + 2 -- 2015/12/31 까지
               )
       )
order by 1