5일차에 배운 내용을 정리하였다.
목차는 다음과 같다. :
01 날짜 파싱 시 유의사항
02 변환 함수
-01 to_number
1) 숫자 -> 문자
2) 문자 -> 숫자
-02 to_char
-03 to_date
03 null 치환 함수
-02 nvl2
-03 coalesce
-04 nullif
01 날짜 파싱 시 유의사항
두 자리 연도에 대한 해석을 1900년도 또는 2000년도로 각각 해석하기 위한 포맷이 존재한다.
1) RR(Round year / Rolling year)
두 자리 연도가 1~49인 경우 : 2000년대
두 자리 연도가 50~99 : 1900년대
ex) 99년 -> 1999년
01년 -> 2001년
select to_date('26/03/11', 'yy/mm/dd') date1,
to_date('01/03/11', 'rr/mm/dd') date2,
to_date('99/03/11', 'rr/mm/dd') date3,
to_date('49/03/11', 'rr/mm/dd') date4,
to_date('50/03/11', 'rr/mm/dd') date5
from dual;

2) YY(Year, last 2 digits) : 2000년대
2000년대로 모두 취급
* 외우기 번거롭다면 1900년대 데이터는 rr을, 2000년대 데이터는 yy로 이용한다 정도로 이해해도 괜찮다.
만약 정말 1948년에 대한 해석이 필요할 시, 2자리로 표기한 년도를 rr, yy를 사용하여 해석하는 것보다 4자리로 맞추는 것이 더 났다. (rr, yy인지까지 고려하면 복잡해지는 경우가 많다.)
=> 두 자리 연도에 대한 해석이 되지 않도록 아예 4자리 연도로 바꾼 후 to_date를 통해 날짜변환을 하는 것이 좋다.
select to_date('49/12/25', 'rr/mm/dd'),
to_date('49/12/25', 'yy/mm/dd'),
to_date('19'||'49/12/25', 'yyyy/mm/dd')
from dual;

02 변환 함수
데이터 타입을 변환하기 위해 사용한다.
숫자 (3) -> 문자('03')
문자('03') -> 숫자(3)
문자 -> 날짜
-01 to_number
to_number(대상)
문자와 숫자를 비교할 시, 연산과정에서 문자데이터를 숫자타입으로 자동으로 변환한다.
이를 묵시적 형 변환이라고 하며, 결과 출력은 정상적으로 하나 성능이 떨어지기에 데이터타입을 맞추는 것이 중요하다.
select '100' + 1
from dual;
select to_number('100' + 1)
from dual;

-02 to_char
1) 숫자 -> 문자
to_char(대상[, 포맷])
숫자 출력 형식을 변경할 때 사용한다.
ex) 1000 -> 1,000
1000 -> $1000
1000 -> 1000.00 (정수지이지만 실수의 형태를 강제로 취해야 할 때)
포맷은 다음과 같다.
- 9 : 한자리 숫자를 표현, 부족한 자릿수를 공백으로 채움
- 0 : 한자리 숫자를 표현, 부족한 자릿수를 공백으로 채움
- , : 천 단위 구분기호
- & : 달러기호
- . : 소숫점 표현기호
select to_char(100)
from dual;

원본 크기보다 포맷이 작은 자릿수면 출력이 되지 않으며, 천 단위 구분기호 같은 경우에도 ',' 위치를 직접 지정해야 한다.
한 자리 숫자를 표현하는 0과 9의 경우 원본 크기 < 포맷일 시 남는 길이를 추가적으로 0으로 출력하냐 아니냐의 차이가 있다.
또한 to_char를 통한 치환의 경우 앞에 공백이 하나씩 발생하며, 이를 제거하고 싶을 시 trim 함수를 이용하면 된다.
select to_char(100, '9999'),
to_char(100, '0000'),
to_char(100, '0999')
from dual;

치환하려는 대상 앞의 길이는 0으로 채워지느냐 그렇지 않느냐의 차이지만, 소숫점 부분은 0과 9의 사용에 무관하게 무조건 0으로 출력된다.
select to_char(100, '$999.99'),
to_char(100, '$000.00')
from dual;

-03 to_date
날짜의 출력 형식을 변경한다.
ex) '2026/03/11' -> '11/03/2026' 또는 '2026'
select to_date(20260311, 'yyyymmdd'), -- 숫자 -> 날짜(추천X, 파이썬에서는 불가)
to_date('2026-03-11', 'yyyy-mm-dd') -- 문자 -> 날짜
from dual;

+) 일 시간 분
30분 후의 시간 구하기
select sysdate + 30*(1/24/60)
from dual;

alter session set nls_date_format = 'mm/dd/yyyy';
select empno, name, emp_type, birthday
from emp2
where birthday > '1982/01/01';
+) 지정한 월이 부족합니다 에러 발생 시
같은 쿼리여도 날짜 포맷이 어떻게 설정되었는지를 확인해야 한다.
그것이 아니라면 to_day를 통해 설정
select empno, name, emp_type, birthday
from emp2
where birthday > to_date('1982/01/01', 'yyyy/mm/dd');
03 null 치환 함수
NULL을 포함한 산술연산(+, -, *, /) 결과는 항상 NULL을 리턴하기 때문에 NULL을 치환하여 산술연산이 가능토록 해준다.
-01 nvl
nvl(대상, 치환값)
대상을 치환값으로 리턴한다.
NULL을 대상으로 지정하면 치환값으로 리턴한다.
일반적으로 null을 포함한 산술연산은 결과로 null을 리턴한다.
select 300 + null
from dual;

select 300 + nvl(null, 0)
from dual;

그러나 nvl(null,0) 을 통해 null을 0으로 치환하였고, 300+0의 연산이 진행되어 300이라는 결과를 리턴하였음을 확인할 수 있다.
-02 nvl2
nvl2(대상, null이 아닐 때 치환값, null일 때 치환값)
대상이 null이 아니라면 null이 아닐 때의 지정해준 치환값을 리턴하며, null이라면 null일 때의 치환값을 리턴한다.
null=null 리턴이 아니다.
emp 테이블에서 직원별 급여(COMM)는 다음과 같다.
select *
from emp;

급여에 10을 더한 수를 추가하고 싶다면 COMM이 NULL인 직원들의 COMM+10 결과는 NULL로 반환될 것이다.
급여에 상여금을 추가한 총 급여를 구할 수 없는 상황인 것이다. 그러나 nvl2 함수를 통해 다음과 같은 결과를 얻을 수 있다.
select comm,
nvl2(comm, comm+10, 0)
from emp;

COMM이 NULL이었던 직원들의 총 급여를 조회할 수 있다.
또한 nvl2는 치환값 두 개가 다른 데이터 타입인 경우 하나의 데이터 타입을 가지게 된다.
emp 테이블에서 직원의 이름, 급여, 보너스, nal2을 통한 보너스 지급 유무를 구하게 되었을 시, 'O' 와 'X'는 두 개 모두 문자 형태로 문제없이 조회가 가능하다.
select ename, sal, comm, nvl2(comm, 'O', 'X')
from emp;

그러나 문자인 'O' 대신에 숫자 0을 집어넣게 되면 숫자 타입으로 지정된 열에는 문자 타입이 입력될 수 없어 결과가 조회되지 않고 다음과 같은 오류가 발생하게 된다.
select ename, sal, comm, nvl2(comm, 0, 'X') -- error
from emp;

그러나 문자인 'O'가 먼저 오고, 뒤에 숫자인 0이 올 시에는 결과가 정상적으로 조회된다. 두 번째 인수가 문자타입이기에 숫자의 형태도 입력 가능하기 때문이다. 따라서 어떤 데이터타입의 인수가 먼저 작성되는지를 고려해야 한다.
select ename, sal, comm, nvl2(comm, 'O', 0) -- 두번째 인수가 문자타입으로 정상
from emp;

-03 coalesce
coalesce(대상, 값1, 값2, 값3,......)
대상을 기준으로 값을 하나씩 조회하며 null이 아닌 값 중 가장 처음에 조회되는 값을 리턴한다.
col1 -(col1이 null이면 다음 열 조회)-> col2 -( col2이 null이면 다음 열 조회 )->col3...
create table null_test1(
col1 number,
col2 number,
col3 number,
col4 number);
insert into null_test1 values(null, 10, 20, 30);
insert into null_test1 values(10, null, 30, 40);
insert into null_test1 values(20, 30, null, null);
insert into null_test1 values(null, null, 20, 30);
commit;
select * from null_test1;

다음과 같은 테이블이 있다고 가정하였을 때 coalesce를 통해 null이 아닌 최초의 값을 반환하면 결과는 다음과 같이 나온다.
select coalesce(col1, col2, col3, col4)
from null_test1;

-04 nullif
nullif(대상, 값)
대상과 값이 일치하면 null을 리턴하며, 일치하지 않으면 원래 값을 유지한다.
select ename, comm, nullif(comm, 500)
from EMP
where deptno = 30;

ENAME이 WARD의 경우 COMM이 500이지만, nullif(COMM, 500)은 COMM의 값이 500에 일치하기 때문에 500이 아닌 NULL를 리턴한다.
nullif(COMM, 500)의 500은 비교대상일 뿐 출력되는 값이 아니다.
'아이티윌_데이터 분석 55기 > 강의내용 필기_SQL' 카테고리의 다른 글
| #7 7일차_JOIN : 조인 실습, 표준 조인 (0) | 2026.03.13 |
|---|---|
| #6 6일차_ JOIN : equi join, non equi join, 세 개 이상 테이블의 조인 (0) | 2026.03.12 |
| #4 4일차_조건 치환, 숫자 함수, 날짜 함수 (0) | 2026.03.10 |
| #3 3일차_ORDER BY, 문자 함수 (0) | 2026.03.09 |
| #2) 2일차_SELECT문 : WHERE, GROUP BY, HAVING (0) | 2026.03.08 |