2022.05.27 - [개발/오라클 SQL] - 한달 달력 구해보기, 오라클에서 날짜계산, 바인딩 변수
이전 포스트 풀이과정입니다.
/*1차 필요한 컬럼 값 만들기*/
SELECT
LEVEL AS "DAY"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'DD') AS "TO_CHAR"
,EXTRACT(DAY FROM TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1) AS "EXTRACT"
,TO_CHAR(TO_DATE(:ST_YYYYMM+1, 'YYYYMM')-1, 'DD') AS "마지막일"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D') AS "요일 인덱스"
,TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D') AS "내가 속한날 첫 일"
FROM DUAL
CONNECT BY LEVEL <=TO_CHAR(TO_DATE(:ST_YYYYMM+1, 'YYYYMM')-1, 'DD');
"DAY", "TO_CHAR", "EXTRACT" 는 같은 값을 다르게 뽑는 방식입니다.
추가로 오른쪽 정렬이 숫자, 왼쪽 정렬이 문자열을 의미합니다.
보통 모든 변환은 TO_CHAR를 제일 많이 사용합니다. 지원하는 기능도 많고 문자열이기 때문에 매개체 역할도 가능하기 때문입니다.
/*DECODE 사용한 피벗 */
SELECT
"내가 속한날 첫 일"
,DECODE("요일 인덱스", 1 , "DAY") AS "일"
,DECODE("요일 인덱스", 2 , "DAY") AS "월"
,DECODE("요일 인덱스", 3 , "DAY") AS "화"
,DECODE("요일 인덱스", 4 , "DAY") AS "수"
,DECODE("요일 인덱스", 5 , "DAY") AS "목"
,DECODE("요일 인덱스", 6 , "DAY") AS "금"
,DECODE("요일 인덱스", 7 , "DAY") AS "토"
FROM
(
SELECT
LEVEL AS "DAY"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'DD') AS "TO_CHAR"
,EXTRACT(DAY FROM TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1) AS "EXTRACT"
,TO_CHAR(TO_DATE(:ST_YYYYMM+1, 'YYYYMM')-1, 'DD') AS "마지막일"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D') "요일 인덱스"
,TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D') AS "내가 속한날 첫 일"
FROM DUAL
CONNECT BY LEVEL <=TO_CHAR(TO_DATE(:ST_YYYYMM+1, 'YYYYMM')-1, 'DD')
)
ORDER BY DAY
;
/*GROUP BY 내가 속한날 첫 일_ 로 컬럼 값 압축*/
SELECT
"내가 속한날 첫 일"
,SUM(DECODE("요일 인덱스", 1 , "DAY")) AS "일"
,MIN(DECODE("요일 인덱스", 2 , "DAY")) AS "월"
,MAX(DECODE("요일 인덱스", 3 , "DAY")) AS "화"
,SUM(DECODE("요일 인덱스", 4 , "DAY")) AS "수"
,MIN(DECODE("요일 인덱스", 5 , "DAY")) AS "목"
,MAX(DECODE("요일 인덱스", 6 , "DAY")) AS "금"
,SUM(DECODE("요일 인덱스", 7 , "DAY")) AS "토"
FROM
(
SELECT
LEVEL AS "DAY"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'DD') AS "TO_CHAR"
,EXTRACT(DAY FROM TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1) AS "EXTRACT"
,TO_CHAR(TO_DATE(:ST_YYYYMM+1, 'YYYYMM')-1, 'DD') AS "마지막일"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D') "요일 인덱스"
,TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D') AS "내가 속한날 첫 일"
FROM DUAL
CONNECT BY LEVEL <=TO_CHAR(TO_DATE(:ST_YYYYMM+1, 'YYYYMM')-1, 'DD')
)
GROUP BY "내가 속한날 첫 일"
ORDER BY MIN(DAY)
;
마지막으로 인라인뷰 없이 똑같은 결과를 만들기입니다.
위 SQL을 기반으로 만들어 보기실 권장합니다.
*인라인뷰 사용 안한 최종 쿼리*/
SELECT
TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D') AS "내가 속한날 첫 일"
,SUM(DECODE(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D'), 1 , LEVEL)) AS "일"
,MIN(DECODE(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D'), 2 , LEVEL)) AS "월"
,MAX(DECODE(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D'), 3 , LEVEL)) AS "화"
,SUM(DECODE(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D'), 4 , LEVEL)) AS "수"
,MIN(DECODE(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D'), 5 , LEVEL)) AS "목"
,MAX(DECODE(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D'), 6 , LEVEL)) AS "금"
,SUM(DECODE(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D'), 7 , LEVEL)) AS "토"
FROM DUAL
CONNECT BY LEVEL <=TO_CHAR(TO_DATE(:ST_YYYYMM+1, 'YYYYMM')-1, 'DD')
GROUP BY TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')+LEVEL-1, 'D')
ORDER BY MIN(LEVEL)
;
'개발 > 오라클 SQL' 카테고리의 다른 글
문자열 다루기 핵심 TRANSLATE (1) | 2022.11.25 |
---|---|
IN, NOT IN, EXISTS, NOT EXISTS (0) | 2022.11.10 |
마이바티스 null 체크 (0) | 2022.09.28 |
정규식을 통한 Mybatis Sql Injection 처리 (0) | 2022.06.29 |
바인드 변수 두 개를 받아 그 사이 달력 찍기 (0) | 2022.06.02 |