아마도 날짜로만 쿼리 포스트는 마지막일 듯 합니다.
SELECT
TO_DATE(:ST_YYYYMM, 'YYYYMM') "시작일"
,ADD_MONTHS(TO_DATE(:ET_YYYYMM , 'YYYYMM'),1)-1 "마지막일"
FROM DUAL;
시작점과 끝점 구하기
SELECT
TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL "DAY"
,ADD_MONTHS(TO_DATE(:ET_YYYYMM , 'YYYYMM'),1)-1 "마지막일"
,COUNT(*) OVER()
FROM DUAL
CONNECT BY TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL <= ADD_MONTHS(TO_DATE(:ET_YYYYMM , 'YYYYMM'),1)-1;
시작점과 끝점 사이 ROW값 구하기
SELECT
TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL "DAY"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') "속한 요일"
,TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'D') "속한 주"
,TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'MM') "속한 달"
FROM DUAL
CONNECT BY TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL <= ADD_MONTHS(TO_DATE(:ET_YYYYMM , 'YYYYMM'),1)-1;
필요한 컬럼 값 구하기
SELECT
DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 1, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')) "일"
,DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 2, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')) "월"
,DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 3, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')) "화"
,DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 4, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')) "수"
,DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 5, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')) "목"
,DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 6, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')) "금"
,DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 7, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')) "토"
,TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL "DAY"
,TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') "속한 요일"
,TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'D') "속한 주"
,TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'MM') "속한 달"
FROM DUAL
CONNECT BY TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL <= ADD_MONTHS(TO_DATE(:ET_YYYYMM , 'YYYYMM'),1)-1;
"DAY" 행을 DECODE로 강제로 주 단위로 찢기
SELECT
TO_CHAR(DECODE(MIN(TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD')),1, MIN(TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'MM'))),'MM') "달"
,RANK() OVER(PARTITION BY TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'MM') ORDER BY MIN(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL)) || '주차' "주차"
,SUM(DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 1, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD'))) "일"
,SUM(DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 2, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD'))) "월"
,SUM(DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 3, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD'))) "화"
,SUM(DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 4, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD'))) "수"
,SUM(DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 5, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD'))) "목"
,SUM(DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 6, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD'))) "금"
,SUM(DECODE( TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'D') , 7, TO_CHAR(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL,'DD'))) "토"
FROM DUAL
CONNECT BY TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL <= ADD_MONTHS(TO_DATE(:ET_YYYYMM , 'YYYYMM'),1)-1
GROUP BY TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'MM'),TRUNC(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL, 'D')
ORDER BY MIN(TO_DATE(:ST_YYYYMM, 'YYYYMM')-1+LEVEL)
;
찢은 컬럼을 GROUP BY 표현식으로 하나의 행으로 합침
부가적으로 몇 월, 몇 주차 표시
마무리
날짜를 기준으로 그룹화를 하는 것은 꽤나 실전적인 쿼리입니다.
조금만 생각해보면 답이 나옵니다. 내가 쇼핑몰을 개발하던, 공장 재고관리를 하던, ... 고객이 원하는 대부분의 통계는 날짜 더나아가 시간 정보로 보길 원하거든요.
이렇게 시간기준으로 집계한 원본 소스값에 WHERE 절을 추가해서 검색 조건을 달게 됩니다.
'개발 > 오라클 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 |