SQL

[ORACLE] 오라클에서의 NULL

hjkongkong 2025. 7. 16. 10:44

# NULL  관련 함수

함수 설명
NVL(expr1,expr2) expr1이 NULL이 아니면 expr1, NULL이면 expr2 반환
NVL2(expr1,expr2,expr3) expr1이 NULL이 아니면 expr2, NULL이면 expr3 반환
COALESCE(expr1,expr2,...) 매개변수 expr 중에서 NULL이 아닌 첫번째 expr 반환 
LNNVL(조건식) 조건식의 결과가 FALSE 또는 UNKNOWN이면 TRUE, TRUE이면 FALSE를 반환
NULLIF(expr1,expr2) expr1 = expr2 이면 NULL 반환, 같지 않으면 expr1 반환

NVL2 예시
NULLIF 예시

/* NULL 관련 함수 */
-- NVL 예시
SELECT MANAGER_ID, EMPLOYEE_ID, 
       NVL(MANAGER_ID, EMPLOYEE_ID)
FROM EMPLOYEES
WHERE MANAGER_ID IS NULL OR ROWNUM <= 5;

-- NVL2 예시
SELECT EMPLOYEE_ID,
       NVL2(COMMISSION_PCT, SALARY+ SALARY*COMMISSION_PCT, SALARY) AS SALARY2
FROM EMPLOYEES;

-- NVL으로 NVL2처럼 만들어보기
SELECT EMPLOYEE_ID,
       NVL2(COMMISSION_PCT, SALARY+ SALARY*COMMISSION_PCT, SALARY) AS SALARY_NVL2,
       (NVL(COMMISSION_PCT,0)+1)*SALARY AS SALARY_NVL1
FROM EMPLOYEES;

-- SALARY_NVL1 == SALARY_NVL2 확인
SELECT * FROM(
SELECT EMPLOYEE_ID,
       NVL2(COMMISSION_PCT, SALARY+ SALARY*COMMISSION_PCT, SALARY) AS SALARY_NVL2,
       (NVL(COMMISSION_PCT,0)+1)*SALARY AS SALARY_NVL1
FROM EMPLOYEES) A
WHERE A.SALARY_NVL1 <> SALARY_NVL2;

-- COALESCE
SELECT EMPLOYEE_ID, SALARY, COMMISSION_PCT,
       COALESCE(SALARY * COMMISSION_PCT, SALARY) AS SALARY2
FROM EMPLOYEES;

-- 같은 결과를 NVL과 LNNVL을 이용해서 만들어보자
-- COMMISSION_PCT가 0.2보다 작은 직원의 수를 세고자 한다.(NULL 포함)
SELECT COUNT(*)
FROM EMPLOYEES
WHERE NVL(COMMISSION_PCT,0) < 0.2;
-- LNNVL 함수 내부의 조건은 조회하려고 하는 조건의 반대 조건으로 설정!!!
SELECT COUNT(*)
FROM EMPLOYEES
WHERE LNNVL(COMMISSION_PCT >= 0.2);

-- NULLIF( 둘이 같다면 NULL 반환)
SELECT EMPLOYEE_ID,
       TO_CHAR(START_DATE, 'YYYY') START_YEAR,
       TO_CHAR(END_DATE, 'YYYY') END_YEAR,
       NULLIF(TO_CHAR(END_DATE, 'YYYY'),TO_CHAR(START_DATE, 'YYYY')) NULLIF_YEAR
FROM JOB_HISTORY
WHERE NULLIF(TO_CHAR(END_DATE, 'YYYY'),TO_CHAR(START_DATE, 'YYYY'))IS NOT NULL;

 


# NULL값은 연산부호 값을 사용할 수 없다.

※ ORACLE의 경우 다음과 같은 조건식을 허용하지 않음 
- SALARY = NULL
- SALARY <> NULL

 

198번 직원의 SALARY를 NULL 값으로 치환함

<
>=
=

모두 결과가 안나옴

그럼 199번 직원으로 바꿔본다면

잘 된다. 

 

NULL은 IS NULL, IS NOT NULL의 형태로 비교한다.

 

# 혹시 IN 조건식으로도 안될까?

안된다.


# NULL 값 정렬하기

기본적으로 오라클은 NULL값을 가장 큰 값으로 인식한다.

그렇다면 오라클에서 NULL값을 가장 작은 값으로 정렬할 순 없을까?

NULL LAST를 설정하면된다.

-- 오라클은 기본적으로 NULL을 가장 마지막 값으로 정렬함

-- NULL 값을 명시적으로 가장 처음 정렬
SELECT * FROM EX3_X 
ORDER BY SALARY ASC NULLS FIRST;

-- NULL 값을 명시적으로 마지막에 정렬
SELECT * FROM EX3_X 
ORDER BY SALARY DESC NULLS LAST;

여담인데, 일전에 들었던 튜닝 수업에서 DBA 님이 개발자들의 NULL 공포증에 대해 설명하시면서,

함수를 사용하면 인덱스가 무효화되거나 비효율적으로 동작할 수 있기 때문에

NULL 처리 함수들 남발을 하지 말라고 경고 아닌 경고를 하셨던 기억이 난다.

하지만 NULL 때문에 오류 날 거 생각하면 나도 모르게 손이 가는 건 어쩔 수 없다!ㅜㅜ

반응형

'SQL' 카테고리의 다른 글

[ORACLE] 숫자함수  (0) 2025.07.16
[SQL] IN과 EXISTS  (0) 2025.07.16
[SQL] CASE WHEN 표현  (0) 2025.07.16
[ORACLE] Pseudo-column 의사컬럼  (0) 2025.07.16
[SQL] TCL - COMMIT, ROLLBACK, SAVEPOINT  (0) 2025.07.16