일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 오라클에러
- CodeUp
- BaekJoon
- oracle
- 자바별찍기
- Python
- 백준
- 별찍기
- db
- 오라클
- if문
- for문
- 오라클에러코드
- 반복문
- commit
- 조건문
- java
- 파이썬
- 코드업문제풀이
- 문제풀이
- 자바문제풀이
- 자바
- 오늘부터 개발자
- 오늘부터개발자
- 임시테이블생성
- 코드업
- mysql
- 에러코드
- 자바문제
- SQL
- Today
- Total
매일 1%씩, 개발자로 성장하기
[Oracle] 년월을 입력받아 달력 생성 및 출력하는 쿼리 만들기 본문
시행착오가 있었지만 년월을 입력받아 달력 생성 및 출력하는 쿼리 만들기에 성공하였다.
CASE문 대신 DECODE 함수를 쓰면 더 간단하게 출력 가능하다!

첫 번째 시도 - 실패
문제점 1. &calendar 선언을 중복으로 하였음 (3번)
문제점 2. 199901를 입력시 정렬이 깨짐 즉, 주차 계산을 제대로 못하였음
SELECT Min(CASE
WHEN To_char(dates, 'D') = 1 THEN To_char(dates, 'DD')
END) 일,
Min(CASE
WHEN To_char(dates, 'D') = 2 THEN To_char(dates, 'DD')
END) 월,
Min(CASE
WHEN To_char(dates, 'D') = 3 THEN To_char(dates, 'DD')
END) 화,
Min(CASE
WHEN To_char(dates, 'D') = 4 THEN To_char(dates, 'DD')
END) 수,
Min(CASE
WHEN To_char(dates, 'D') = 5 THEN To_char(dates, 'DD')
END) 목,
Min(CASE
WHEN To_char(dates, 'D') = 6 THEN To_char(dates, 'DD')
END) 금,
Min(CASE
WHEN To_char(dates, 'D') = 7 THEN To_char(dates, 'DD')
END) 토
FROM (SELECT ( To_date(&calendar, 'YYYYMM') + LEVEL - 1 ) dates,
LEVEL
FROM dual
CONNECT BY ( To_date(&calendar, 'YYYYMM') + LEVEL - 1 ) <= Last_day(
To_date(&calendar, 'YYYYMM')))
GROUP BY ( CASE
WHEN To_char(dates, 'D') = 1 THEN To_char(dates, 'IW') + 1
ELSE To_char(dates, 'IW') + 0
END )
ORDER BY ( CASE
WHEN To_char(dates, 'D') = 1 THEN To_char(dates, 'IW') + 1
ELSE To_char(dates, 'IW') + 0
END );
두 번째 시도 - 성공 (일요일부터 출력)
문제점 해결 1. 변수를 제일 처음 select 하는 절에 한번만 선언
문제점 해결 2.
1) TRUNC (SYSDATE + LEVEL - 1, 'd') : TRUNC와 'd'옵션을 사용하여 해당 주의 요일로 초기화 (일요일로 시작)
2) TRUNC (SYSDATE + LEVEL - 1, 'y') : TRUNC와 'y'옵션을 사용하여 해당 주의 월,일 초기화 (01-01로 시작)
3) TRUNC(TRUNC (SYSDATE + LEVEL - 1, 'y', 'd'))
4) 계산법 : (주간의 첫 날짜(일요일) - 1월1일 주간의 첫 날짜(일요일)) / 7 + 1
근데 여기서 7 + 1 안하고 7해도 답이 나오는데..어떤 차이인지 아직 발견하지 못하였다..
+)참고 : 날짜와 관련한 TRUNC 활용 (TRUNC(sysdate, 'd'))
▶ 'w' : 매월1일 요일을 기준한 주초일자.
▶ 'ww' : 매년 1월1일 요일을 기준한 주초일자.
▶ 'iw' : 주초 월요일일자.
▶ 'd' / 'dy' / 'day' : 주초 일요일 일자.
▶ 'month' : 기준달의 1일자.
▶ 'year' : 기준년의 1월 1일자.
SELECT Min(CASE
WHEN To_char(dates, 'D') = 1 THEN To_char(dates, 'DD')
END) 일,
Min(CASE
WHEN To_char(dates, 'D') = 2 THEN To_char(dates, 'DD')
END) 월,
Min(CASE
WHEN To_char(dates, 'D') = 3 THEN To_char(dates, 'DD')
END) 화,
Min(CASE
WHEN To_char(dates, 'D') = 4 THEN To_char(dates, 'DD')
END) 수,
Min(CASE
WHEN To_char(dates, 'D') = 5 THEN To_char(dates, 'DD')
END) 목,
Min(CASE
WHEN To_char(dates, 'D') = 6 THEN To_char(dates, 'DD')
END) 금,
Min(CASE
WHEN To_char(dates, 'D') = 7 THEN To_char(dates, 'DD')
END) 토
FROM (SELECT dates,
week
FROM (SELECT base_mon + LEVEL - 1 dates,
( Trunc(base_mon + LEVEL - 1, 'd') - Trunc(
Trunc(base_mon + LEVEL - 1, 'y'), 'd' ) ) / 7 WEEK
-- 주 계산 후 정렬에 사용
FROM (SELECT To_date('&calendar', 'yyyymm') base_mon
-- 변수 선언 1번으로 수정
FROM dual)
CONNECT BY LEVEL <= To_char(Last_day(base_mon), 'dd')))
GROUP BY week
ORDER BY week;
세 번째 시도 - 성공 (월요일부터 출력)
월요일부터 출력시 TO_CHAR( date [,'fmt' [,'nlsparam']]) 오라클 설정변경
SELECT Min(CASE
WHEN To_char(dates, 'D') = 2 THEN To_char(dates, 'DD')
END) 월,
Min(CASE
WHEN To_char(dates, 'D') = 3 THEN To_char(dates, 'DD')
END) 화,
Min(CASE
WHEN To_char(dates, 'D') = 4 THEN To_char(dates, 'DD')
END) 수,
Min(CASE
WHEN To_char(dates, 'D') = 5 THEN To_char(dates, 'DD')
END) 목,
Min(CASE
WHEN To_char(dates, 'D') = 6 THEN To_char(dates, 'DD')
END) 금,
Min(CASE
WHEN To_char(dates, 'D') = 7 THEN To_char(dates, 'DD')
END) 토,
Min(CASE
WHEN To_char(dates, 'D') = 1 THEN To_char(dates, 'DD')
END) 일
FROM (SELECT dates,
CASE
WHEN To_char(dates, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN') = 'SUN'
THEN
--'DY'를 통해서 각 요일의 앞글자만 출력
To_number(week) - 1
ELSE week
END week
FROM (SELECT base_mon + LEVEL - 1 dates,
( Trunc(base_mon + LEVEL - 1, 'd') - Trunc(
Trunc(base_mon + LEVEL - 1, 'y'), 'd'
) ) / 7 WEEK
FROM (SELECT To_date('&calendar', 'yyyymm') base_mon
FROM dual)
CONNECT BY LEVEL <= To_char(Last_day(base_mon), 'dd')))
GROUP BY week
ORDER BY week;
'Database > Oracle' 카테고리의 다른 글
[Oracle] COALESCE 함수 : NULL이 아닌 첫 번째 표현식을 반환 (0) | 2022.08.16 |
---|---|
[Oracle] WITH절 (WITH AS) 임시테이블 생성 및 문법 사용 (0) | 2022.08.13 |
[Oracle] 트리거(Trigger) 문법 및 생성 (0) | 2022.08.09 |
[Oracle] ORACLE 스키마(구조) 조회 및 Table 목록, Column 목록 조회하는 쿼리 (0) | 2022.07.31 |
[Oracle] PL/SQL - 반복문 구구단 출력하기 (0) | 2022.07.26 |