현재 데이터베이스를 공부하고 있는 학생인데 궁금한 것이 있습니다.!!
날짜 테이블이 있고 공휴일 테이블이 따로 있습니다.
날짜 테이블에서 해당 날짜에서 하루를 더하여 토요일일 경우 월요일로 만들고 일요일일 경우 월요일로 만드는 것은
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(화) -> 이렇게 하는 방법을 모르겠습니다!ㅠㅠ
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 32 33 34 35 36 37 | -- 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 ; |
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 32 33 34 35 36 37 38 39 40 41 42 | -- 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 사용시 버그가 있네요. -- 버그 발생 피하려고 코드를 바꿨습니다. |