by 수달 [2023.10.11 16:03:23]
oracle에서 iso 기준으로 주차별 계산을 하려고 하는데요,
iso기준인 iw를 사용하면 1~52주차의 값을 보여주더라구요.
저는 월별 주차를 나타내고 싶은데 (즉, 9월 37주차가 아닌 9월 2주차로 나타내고 싶습니다.) 혹시 방법이 없을까요?
해당 일의 주차 - 해당월의 1일의 주차 + 1
이런식의 로직으로 처리 가능하지 않을까요?
TO_CHAR(TO_DATE(date_column), 'IW') - TO_CHAR(TO_DATE(date_column), 'WW') + 1
이거 말씀하시는 걸까요?
이렇게 하면 제대로 안나오는 것 같아요ㅠ
TO_CHAR(TO_DATE(date_column), 'WW') - TO_CHAR(TRUNC(TO_DATE(date_column),'month'), 'WW') + 1
이런 형태면 되지 않을까요?
아~ 그렇군요. 우주민님께서 말씀하신게 이런 방식일까요?
select to_char(sysdate,'IW') - to_char(trunc(sysdate,'MM'),'IW') + 1 from dual;
우주민님께서 말씀해주신 방법으로 하면 제가 원했던 1~5주차가 나오긴 하는데 ISO 기준이 아니어서 안되겠네요ㅠㅠ
IW로 바꿔서 하면 값이 이상하게 나오고.. 마땅한 방법이 없나봐요
아 이 방법도 보긴 했는데 'W'는 월의 1일 기준으로 주차 계산을 한다고 하더라구요!
저는 ISO 기준(매월 월요일 시작 기준)을 따르되 몇월 1~5주차로 나타내고 싶어서요! 방법이 마땅치 않네요ㅠㅠ
월의 주가 겹치는 부분에 대한 처리 기준을 제시해 주셔야 합니다.
원본 대비 결과표 샘플 데이터를 통해서
WITH t AS
(
SELECT TO_DATE('20221225', 'yyyymmdd') + LEVEL - 1 dt
FROM dual
CONNECT BY LEVEL <= 380
)
SELECT TO_CHAR(dt, 'yyyy.mm.dd') ymd
, TO_CHAR(dt, 'iyyy') iyyy
, TO_CHAR(dt, 'iw') iw
, TO_CHAR(w, 'mm') imm
, (w - m) / 7 + 1 imw
FROM (SELECT dt
, TRUNC(dt, 'iw') + 3 w -- 주 목요일
, NEXT_DAY(TRUNC(TRUNC(dt, 'iw') + 3, 'mm') - 1, 5) m -- 월 첫 목요일
FROM t
)
;
아 저도 월의 주가 겹치는 부분이 약간 걱정 됐는데요,
예를 들어 22년 1월~22년 2월에서, 2022-01-31~2022-02-06은 2월 1주차가 되도록 처리하고 싶었습니다.
근데 예시로 들어주신 쿼리 돌려보니 제가 원하는 방향으로 나오네요!! 참고해서 쿼리 짜보겠습니다 감사합니다~
WITH t AS
(
SELECT TO_DATE('20220123', 'yyyymmdd') + LEVEL - 1 dt
FROM dual
CONNECT BY LEVEL <= 30
)
-- 좀 더 간결하게 가능하네요.(목요일 기준 주차)
SELECT TO_CHAR(dt, 'yyyy.mm.dd') ymd
, TO_CHAR(dt, 'iyyy') iyyy
, TO_CHAR(dt, 'iw') iw
, TO_CHAR(thu, 'mm') imm
, TO_CHAR(thu, 'w') imw
FROM (SELECT dt
, TRUNC(dt, 'iw') + 3 thu -- 주 목요일
FROM t
)
;
만약에 그럼 제가 가진 테이블을 'A', 'A' 테이블의 날짜데이터를 가진 컬럼 'a_dt' 가 있다면(단, a_dt는 varchar2)
쿼리를 아래처럼 바꾸려고 했는데, ORA-01843: 지정한 월이 부적합합니다. 이런 오류가 나서 어떻게 수정하면 좋을까요ㅠㅠ
WITH t AS
(
SELECT TO_DATE(a_dt, 'yyyymmdd') + LEVEL - 1 dt
FROM A
CONNECT BY LEVEL <= 365
)
SELECT TO_CHAR(dt, 'yyyy.mm.dd') ymd
, TO_CHAR(dt, 'iyyy') iyyy
, TO_CHAR(dt, 'iw') iw
, TO_CHAR(thu, 'mm') imm
, TO_CHAR(thu, 'w') imw
FROM (SELECT dt
, TRUNC(dt, 'iw') + 3 thu
FROM t
)
;
감사합니다!! 공유주신 쿼리 해보니 잘 돌아가는 것 같아요! 덕분에 너무 많은 도움 됐습니다 혹시 추가 질문 있으면 또 답글 드리겠습니다~
1. Connect By LEVEL 구문은 빼셔야 합니다. with 문도 굳이 사용하실 필요 없습니다.
2. 오류 문구 그대로 부적합한 자료가 있는지 확인해 보셔야 합니다.
SELECT a_dt
, TO_CHAR(dt, 'iyyy') iyyy
, TO_CHAR(dt, 'iw') iw
, TO_CHAR(thu, 'mm') imm
, TO_CHAR(thu, 'w') imw
FROM (SELECT a_dt -- 1. 원본(문자형)
, TO_DATE(a_dt, 'yyyymmdd') dt -- 2. 변형(날짜형)
, TRUNC(TO_DATE(a_dt, 'yyyymmdd'), 'iw') + 3 thu -- 3. 해당주 목요일
FROM a
)
;