오래된 쿼리들을 보면 무식하게 반복되는 구조를 가진 것들이 있다. 예를 들면 월 내의 일자 반복인데 아래 예시를 보자.
몇천줄 넘어가는 쿼리들 까보면 다 이런 식이라 한숨부터 나온다. 그나마 일자 반복은 아래 쿼리들을 사용하면 줄일 가능성이라도 있다.
월의 첫째 날을 구하는 쿼리이다.
SELECT TRUNC(TO_DATE('<년월>', 'YYYYMM')) AS FIRST_DAY FROM DUAL;
월의 마지막 날은 더 간단하다.
SELECT LAST_DAY(TO_DATE('<년월>', 'YYYYMM')) AS END_DAY FROM DUAL;
일자 리스트는 LEVEL을 사용하여 출력한다. 레벨 범위를 설정하는 방법은 여러 가지가 있는데, 난 아래 방법이 가장 직관적인 것 같다.
SELECT TRUNC(TO_DATE('<년월>', 'YYYYMM')) + LEVEL -1 AS WK_DATE
FROM DUAL
CONNECT BY LEVEL <= TO_NUMBER(TO_CHAR(LAST_DAY(TO_DATE('<년월>','YYYYMM')), 'DD'));
요일도 간단하게 출력이 가능한데, 사내 프로그램의 경우 주말을 따지는 경우가 많아서 유용하게 쓸 수 있다.
SELECT TO_CHAR('<일자>','DY') FROM DUAL;
오늘과 가장 가까운 다음 특정 요일이 언제인지 구하는 함수도 존재한다.
SELECT NEXT_DAY(TO_DATE('<일자>','YYYYMMDD'),'<요일>') AS NEXT_YOIL FROM DUAL;
조합하면 이렇게 된다.
WITH DAYS AS( --일자 리스트
SELECT TRUNC(TO_DATE('202503', 'YYYYMM')) + LEVEL -1 AS WK_DATE
FROM DUAL
CONNECT BY LEVEL <= TO_NUMBER(TO_CHAR(LAST_DAY(TO_DATE('202503','YYYYMM')), 'DD'))
)
SELECT DAYS.WK_DATE,
TO_CHAR(DAYS.WK_DATE,'DY') AS YOIL,
TRUNC(TO_DATE('202503', 'YYYYMM')) AS FIRST_DAY,
LAST_DAY(TO_DATE('202503', 'YYYYMM')) AS END_DAY
FROM DAYS;
'DB > 공부' 카테고리의 다른 글
[Oracle] SELECT 쿼리 결과로 새로운 테이블 만들기 (0) | 2024.12.01 |
---|