현재 데이터베이스를 공부하고 있는 학생인데 궁금한 것이 있습니다.!!
날짜 테이블이 있고 공휴일 테이블이 따로 있습니다.
날짜 테이블에서 해당 날짜에서 하루를 더하여 토요일일 경우 월요일로 만들고 일요일일 경우 월요일로 만드는 것은
DATE_ADD, DAYOFWEEK를 사용하여 만들었습니다.
다만 해당 날짜가 공휴일일 경우 공휴일 테이블에서 확인하여 +1일을 하여 평일로 만들어서 보여줘야하는데 SELECT로 어찌 날짜를 넘겨야하는지 모르겠습니다!ㅠㅠ
아니면 프로시저에서 CURSOR LOOP를 사용해야하나요?
- 날짜테이블
연도(CHAR4) | 월(CHAR2) | 일(CHAR2) |
2022 | 04 | 04 |
2022 | 04 | 15 |
2022 | 05 | 05 |
2022 | 09 | 09 |
- 공휴일 테이블
연도(CHAR4) | 월(CHAR2) | 일(CHAR2) | 이름(VARCHAR20) |
2022 | 05 | 05 | 어린이날 |
2022 | 09 | 09 | 추석 |
2022 | 09 | 10 | 추석 |
2022 | 09 | 11 | 추석 |
2022 | 09 | 12 | 대체공휴일 |
2022-04-04(월) -> 2022-04-05(화) :1일을 더한 날짜가 평일
2022-04-15(금) -> 2022-04-18(월): 1일을 더한 날짜가 주말이기 때문에 +2일 하여 월요일 평일로 만듬
2022-05-05(목) -> 2022-05-06(금) : 1일을 더한 날짜가 평일
2022-09-09(금) -> 2022-09-13(화) -> 이렇게 하는 방법을 모르겠습니다!ㅠㅠ
-- MySQL -- WITH RECURSIVE t3 AS ( WITH t1 AS ( SELECT '2022' y, '04' m, '04' d UNION ALL SELECT '2022', '04', '15' UNION ALL SELECT '2022', '05', '05' UNION ALL SELECT '2022', '09', '09' ) , t2 AS ( SELECT '2022' y, '05' m, '05' d, '어린이날' nm UNION ALL SELECT '2022', '09', '09', '추석' UNION ALL SELECT '2022', '09', '10', '추석' UNION ALL SELECT '2022', '09', '11', '추석' UNION ALL SELECT '2022', '09', '12', '대체공휴일' ) SELECT CONCAT_WS('-', y, m, d) + INTERVAL 0 DAY dt , CONCAT_WS('-', y, m, d) + INTERVAL 1 DAY dt_next FROM t1 UNION ALL SELECT a.dt , a.dt_next + INTERVAL 1 DAY dt_next FROM t3 a LEFT OUTER JOIN t2 b ON DATE_FORMAT(a.dt_next, '%Y') = b.y AND DATE_FORMAT(a.dt_next, '%m') = b.m AND DATE_FORMAT(a.dt_next, '%d') = b.d WHERE b.y IS NOT NULL OR DAYOFWEEK(a.dt_next) IN (1, 7) ) SELECT dt , MAX(dt_next) dt_next FROM t3 GROUP BY dt ;
-- Oracle -- WITH t1 AS ( SELECT '2022' y, '04' m, '04' d FROM dual UNION ALL SELECT '2022', '04', '15' FROM dual UNION ALL SELECT '2022', '05', '05' FROM dual UNION ALL SELECT '2022', '09', '09' FROM dual ) , t2 AS ( SELECT '2022' y, '05' m, '05' d, '어린이날' nm FROM dual UNION ALL SELECT '2022', '09', '09', '추석' FROM dual UNION ALL SELECT '2022', '09', '10', '추석' FROM dual UNION ALL SELECT '2022', '09', '11', '추석' FROM dual UNION ALL SELECT '2022', '09', '12', '대체공휴일' FROM dual ) , t3(dt, lv) AS ( SELECT y||m||d dt , 1 lv FROM t1 UNION ALL SELECT a.dt , lv + 1 FROM t3 a LEFT OUTER JOIN t2 b ON TO_CHAR(TO_DATE(a.dt, 'yyyymmdd') + lv, 'yyyy') = b.y AND TO_CHAR(TO_DATE(a.dt, 'yyyymmdd') + lv, 'mm') = b.m AND TO_CHAR(TO_DATE(a.dt, 'yyyymmdd') + lv, 'dd') = b.d WHERE b.y IS NOT NULL OR TO_CHAR(TO_DATE(a.dt, 'yyyymmdd') + lv - 1, 'd') IN (1, 7) ) SELECT dt , TO_DATE(dt, 'yyyymmdd') + MAX(lv) dt_next FROM t3 GROUP BY dt ORDER BY dt ; -- Oracle 에서 함수만 바꿔 실행해 봤는데. -- Oracle 의 Recursive 쿼리의 경우 date type 사용시 버그가 있네요. -- 버그 발생 피하려고 코드를 바꿨습니다.