변수의 기록
(데이터베이스)SQL에서의 NULL과 Three-Valued Logic: 반드시 알아야 할 핵심 개념 정리 본문
(데이터베이스)SQL에서의 NULL과 Three-Valued Logic: 반드시 알아야 할 핵심 개념 정리
불광동 물주먹 2025. 5. 14. 21:30SQL에서의 NULL과 Three-Valued Logic: 반드시 알아야 할 핵심 개념 정리
1. 들어가며
SQL을 다룰 때 NULL은 종종 혼란을 불러일으키는 요소입니다. 단순히 "값이 없다"는 개념으로 이해하기 쉽지만, 실제로는 다양한 의미를 내포하고 있고, WHERE 절이나 JOIN, GROUP BY, NOT IN 등과 결합될 때 예상치 못한 결과를 만들어냅니다. 이 글에서는 SQL에서의 NULL의 개념과 Three-Valued Logic(3VL)의 동작 방식, 그리고 실무에서 주의할 점을 정리합니다.
*강의 참고 - 유튜브 쉬운코드
2. NULL의 의미
SQL에서 NULL은 단순한 공백값이나 0이 아니라, 값이 존재하지 않음 또는 알 수 없음을 나타냅니다. 주요 의미는 다음과 같습니다:
- UNKNOWN: 해당 값이 존재하는지 알 수 없음
- UNAVAILABLE: 값이 존재하지만 현재 접근할 수 없음
- WITHHELD: 정책상 감춰져 있음
- NOT APPLICABLE: 해당 속성에 적절한 값이 존재하지 않음
3. Three-Valued Logic (3VL)
SQL은 TRUE, FALSE 외에도 **UNKNOWN**이라는 세 번째 논리값을 가집니다. NULL과 연산을 수행하면 그 결과는 거의 대부분 UNKNOWN이 됩니다.
예시:
A | B | A = B |
1 | 1 | TRUE |
1 | NULL | UNKNOWN |
NULL | NULL | UNKNOWN |
4. WHERE 절과 NULL 처리
WHERE 절은 조건이 TRUE인 튜플만 선택합니다. FALSE와 UNKNOWN 모두 필터링됩니다.
-- 결과 없음
SELECT * FROM users WHERE age = NULL;
-- 올바른 예
SELECT * FROM users WHERE age IS NULL;
5. NOT IN 사용 시 주의
NULL이 포함된 서브쿼리를 NOT IN으로 비교하면 전체 결과가 UNKNOWN이 되어버려서 아무 결과도 반환되지 않을 수 있습니다.
-- 문제가 발생할 수 있음
SELECT * FROM employees
WHERE dept_id NOT IN (SELECT dept_id FROM departments);
6. NOT IN의 평가 방식
NOT IN은 내부적으로 다음과 같이 동작합니다:
-- 예: 3 NOT IN (1, 2, NULL)
-- 내부적으로 다음처럼 평가됨
3 != 1 AND 3 != 2 AND 3 != NULL
이때 3 != NULL의 결과는 UNKNOWN이 됩니다. SQL은 AND 연산에서 하나라도 UNKNOWN이면 전체 결과를 UNKNOWN으로 처리합니다.
즉, NOT IN은 리스트에 NULL이 하나라도 있으면 신뢰할 수 없는 결과를 반환할 수 있습니다.
7. 예제 비교로 이해하기
조건 | 내부 평가 방식 | 결과 |
3 NOT IN (1, 2, 4) | 3≠1 AND 3≠2 AND 3≠4 | TRUE |
3 NOT IN (1, 2, 3) | 3≠1 AND 3≠2 AND 3≠3 → FALSE 포함 | FALSE |
3 NOT IN (1, 3, NULL) | 3≠1 AND 3≠3 (FALSE) AND 3≠NULL (UNKNOWN) | FALSE |
3 NOT IN (1, 2, NULL) | 3≠1 AND 3≠2 AND 3≠NULL (UNKNOWN) | UNKNOWN |
- 마지막 조건은 WHERE 절에서 TRUE가 아닌 경우 필터링되므로 결과에 포함되지 않습니다. 즉, 결과가 없을 수도 있습니다.
해결 방법:
- EXISTS 또는 NOT EXISTS 사용
- 서브쿼리에서 NULL 제거
SELECT * FROM employees
WHERE dept_id NOT IN (
SELECT dept_id FROM departments WHERE dept_id IS NOT NULL
);
6. NULL-safe 연산 방법
SQL 표준에는 없지만, 일부 DBMS(PostgreSQL, Oracle 23c 등)에서는 IS DISTINCT FROM, IS NOT DISTINCT FROM을 지원합니다.
SELECT * FROM table WHERE column IS DISTINCT FROM 5;
예시 비교
A | B | A = B | A IS NOT DISTINCT FROM B |
1 | 1 | TRUE | TRUE |
1 | 2 | FALSE | FALSE |
NULL | NULL | UNKNOWN | TRUE |
1 | NULL | UNKNOWN | FALSE |
7. 그 외 주의사항
- COUNT(column)은 NULL을 제외한 개수만 반환
- COUNT(*)는 NULL 포함 모든 행을 계산
- GROUP BY에서 NULL은 하나의 그룹으로 간주됨
- ORDER BY에서 NULL의 정렬 위치는 DBMS마다 다르며 NULLS FIRST, NULLS LAST로 제어 가능
기본 동작 비교 (오름차순 ASC 기준)
DBMS | ASC 기본 정렬 시 NULL 위치 | DESC 기본 정렬 시 NULL 위치 |
Oracle | NULL이 먼저 (FIRST) | NULL이 나중에 (LAST) |
PostgreSQL | NULL이 먼저 (FIRST) | NULL이 나중에 (LAST) |
MySQL | NULL이 먼저 (FIRST) | NULL이 먼저 (FIRST) ← 주의 |
※ MySQL은 ASC든 DESC든 기본적으로 NULL이 가장 먼저 정렬됩니다.
8. 정리
항목 | 동작/의미 |
NULL 비교 | =로 비교 불가능 → IS NULL 사용 |
연산 결과 | NULL 포함 시 대부분 UNKNOWN |
WHERE 절 조건 결과 | TRUE만 통과, FALSE와 UNKNOWN 제외 |
NOT IN 주의 | NULL 포함 시 전체 결과가 사라질 수 있음 |
NULL-safe 비교 | IS DISTINCT FROM (DBMS에 따라 지원 여부 다름) |
집계 함수 | COUNT(column)은 NULL 제외, COUNT(*)는 포함 |
9. 마무리
NULL은 단순한 비어 있는 값이 아니라, 논리 연산의 흐름과 쿼리 결과에 큰 영향을 미치는 요소입니다. 실무에서 발생할 수 있는 실수를 줄이기 위해서는 NULL과 관련된 연산을 명확히 이해하고, 상황에 맞는 대체 쿼리(EXISTS, IS NULL 등)를 적절히 활용하는 습관이 필요합니다.
'CS지식 > 데이터베이스 (Database)' 카테고리의 다른 글
(데이터베이스)Three-tier Architecture와 Stored Function 활용법 (0) | 2025.05.17 |
---|---|
(데이터베이스)SQL 조인 정리 (0) | 2025.05.14 |
(데이터베이스) SQL 설명 기본 dml ,ddl ,vdl (0) | 2025.05.10 |
(데이터베이스)관계형 데이터 모델 (Relational Data Model) 정리 (0) | 2025.05.07 |
(DB)데이터베이스 시스템의 기본 개념 정리 (0) | 2025.05.07 |