NULL과 3값 논리
NULL을 0·공백과 구분하고 비교 결과 UNKNOWN이 WHERE와 연산에 미치는 영향을 이해한다.
핵심 요약
NULL을 0·공백과 구분하고 비교 결과 UNKNOWN이 WHERE와 연산에 미치는 영향을 이해한다.
핵심 질문
- NULL과 3값 논리에서 반드시 구분해야 할 개념과 결과 규칙은 무엇인가?
- 0건·1건·여러 건과 NULL·동점·중복 데이터에서 결과가 어떻게 달라지는가?
- 비슷해 보이는 문법과 결과가 같아지는 조건, 달라지는 조건은 무엇인가?
- 작은 샘플 데이터를 이용해 결과를 실수 없이 예측하는 순서는 무엇인가?
학습 목표
- NULL의 의미와 3값 논리(TRUE·FALSE·UNKNOWN)를 설명한다.
- NULL이 비교·산술·집계 결과에 미치는 영향을 예측한다.
개념 지도
업무 사실 → 행과 열 → Key·제약조건 → 관계 연산 → 결과 집합
핵심 내용
NULL은 값이 0이거나 빈 문자열이라는 뜻이 아니라 값이 없거나 아직 알 수 없음을 나타낸다. NULL과 일반 비교 연산을 수행하면 결과는 TRUE나 FALSE가 아니라 UNKNOWN이다.
WHERE commission = NULL -- 올바른 NULL 검사 아님
WHERE commission IS NULL -- NULL 검사
WHERE는 조건 결과가 TRUE인 행만 남기므로 FALSE와 UNKNOWN은 모두 제외된다. NULL + 10 같은 산술 결과는 NULL이다. 다만 집계 함수는 일반적으로 NULL을 제외하고 계산하며 COUNT(*)는 행 자체를 세고 COUNT(col)은 해당 컬럼이 NULL이 아닌 행만 센다.
Oracle은 현재 길이 0인 문자값을 NULL로 취급하는 특성이 있지만, 이는 표준 SQL의 일반 규칙으로 확대해 암기하지 않는다.
흔한 오해와 주의점
NULL = NULL은 TRUE가 아니다.NOT IN목록이나 서브쿼리 결과에 NULL이 섞이면 전체 조건이 UNKNOWN이 되어 예상과 달리 행이 나오지 않을 수 있다.SUM,AVG,COUNT(col)의 NULL 제외와COUNT(*)를 구분한다.
문항 풀이 보강: NULL 결과를 행별로 추적하기
NULL 문제는 연산 결과와 WHERE 통과 여부를 분리해 계산한다.
| 식 | 결과 |
|---|---|
NULL = NULL | UNKNOWN |
NULL <> 10 | UNKNOWN |
NULL + 20 | NULL |
NULL IS NULL | TRUE |
COUNT(*) | NULL과 관계없이 행 수 |
COUNT(col) | col이 NULL이 아닌 행 수 |
AVG(col) | NULL을 제외한 합과 건수로 평균 |
SELECT sal / comm
FROM emp
WHERE ename = 'KING';
COMM이 NULL이면 나눗셈 결과도 NULL이다. 0으로 나눌 때의 오류와 NULL 연산을 혼동하지 않는다.
Oracle에서는 길이 0인 문자열 ''을 NULL로 취급한다. SQL Server의 빈 문자열은 NULL과 구별된다. 따라서 DBMS가 명시된 문제에서는 빈 문자열의 저장·비교 규칙을 반드시 확인한다.
NOT IN의 전개
x NOT IN (1, 2, NULL)
= x <> 1 AND x <> 2 AND x <> NULL
= TRUE/FALSE AND UNKNOWN
마지막 UNKNOWN 때문에 전체가 TRUE가 되지 않는다. 부재를 찾는 문제에서는 NOT EXISTS를 우선 검토하고, NOT IN이라면 서브쿼리 결과의 NULL 가능성을 확인한다.
TRUE·FALSE·UNKNOWN 진리표
| A | B | A AND B | A OR B |
|---|---|---|---|
| TRUE | UNKNOWN | UNKNOWN | TRUE |
| FALSE | UNKNOWN | FALSE | UNKNOWN |
| UNKNOWN | UNKNOWN | UNKNOWN | UNKNOWN |
WHERE는 TRUE만 남기므로 FALSE와 UNKNOWN이 모두 제거되지만, NOT·AND·OR 조합에서는 결과가 다르다.
-- NULL과 비교하지 못함
WHERE commission = NULL
-- 올바른 검사
WHERE commission IS NULL
Aggregate와 NULL
COUNT(*)는 행 수를 세고, COUNT(col)은 col이 NULL이 아닌 행만 센다. SUM, AVG, MIN, MAX는 NULL을 제외하지만 모든 값이 NULL이면 결과가 NULL일 수 있다.
값: 10, NULL, 20
COUNT(*) = 3
COUNT(col) = 2
AVG(col) = 15
NVL·COALESCE 주의
NVL(col,0)은 NULL을 실제 0과 같은 업무값으로 해석하는 결정이다. 단순 표시용 치환과 조건식 의미를 구분한다. COALESCE는 왼쪽부터 첫 non-NULL을 반환하며 여러 대안을 표현할 수 있지만 타입 변환 규칙을 확인한다.
Unique와 NULL
Unique Constraint의 NULL 허용 방식은 DBMS 규칙과 복합키 조합에 영향을 받는다. “NULL끼리 같지 않으니 무조건 여러 건 허용”처럼 다른 DBMS까지 일반화하지 말고 Oracle의 실제 제약 동작을 확인한다.
결과를 검증하는 순서
- 각 Query Block이 만드는 한 행의 의미를 먼저 적습니다.
- 조건을 적용하기 전 원본 행과 적용 후 남는 행을 작은 표로 그립니다.
- NULL 비교가
TRUE,FALSE,UNKNOWN중 무엇인지 구분합니다. - 중복 제거, 그룹화, 정렬과 행 제한이 적용되는 순서를 확인합니다.
- 데이터가 0건·1건·여러 건일 때도 같은 규칙이 성립하는지 검증합니다.
실무와 시험에서 함께 확인할 항목
ORDER BY가 없다면 결과 순서를 가정하지 않습니다.- 문자열·숫자·날짜 비교에서는 데이터 타입과 명시적 형변환을 확인합니다.
- 같은 결과처럼 보이는 SQL도 NULL과 중복이 있을 때 달라질 수 있습니다.
- 문법을 외우기 전에 샘플 데이터 3~5행으로 결과를 직접 계산합니다.
마지막 점검
- 작성 순서가 아니라 SQL의 논리적 처리 순서로 결과를 계산합니다.
- NULL을 0이나 빈 값과 같은 것으로 취급하지 않습니다.
ORDER BY가 없는 결과 순서와 DISTINCT 없는 중복 제거를 가정하지 않습니다.- 비슷한 문법은 0건·다건·NULL 데이터를 넣어 결과가 정말 같은지 확인합니다.
복습 문제
WHERE salary <> 3000은 salary가 NULL인 행을 반환하는가?COUNT(*)와COUNT(commission)의 차이는?- 샘플 데이터 3행으로 결과를 직접 계산할 수 있는가?
- NULL이 포함될 때 결과가 달라지는 지점은 어디인가?