이번 강의에서는 우리가 이미 알고 있는 미스터리한 친구 NULL에 대해 좀 더 깊게 파헤쳐볼 거야. 물론 너희가 직접 NULL로 실수할 날도 오겠지만... 미리 알고 있으면 덜 당황하겠지. NULL과 관련된 전형적인 실수 몇 가지를 같이 보자.
실수 1: NULL 체크할 때 일반 = 연산자 쓰기
SQL 처음 배우는 사람들이 제일 많이 하는 실수 중 하나가 NULL 값을 체크할 때 = 연산자를 쓰는 거야.
무슨 일이 일어나냐면?
SELECT *
FROM students
WHERE age = NULL;
이렇게 하면 나이 정보가 없는 학생들을 보여줄 거라고 생각하겠지만, 결과는 아무것도 안 나와. 왜냐면 NULL은 값이 아니라서 일반 비교 연산자가 안 먹혀. SQL 마법서에도 나오지: "NULL은 직접 비교할 수 없다."
그럼 어떻게 해야 하냐?
NULL인지 확인하려면 IS NULL을 써야 해:
SELECT *
FROM students
WHERE age IS NULL;
이제 나이 정보가 없는 학생들이 제대로 나올 거야.
실수 2: 집계 함수가 NULL을 무시함 (COUNT(*) 빼고)
집계 함수로 쿼리할 때 NULL 값은 자동으로 계산에서 빠져. 그래서 결과가 예상과 다를 수 있어.
무슨 일이 일어나냐면?
SELECT AVG(salary) AS avg_salary
FROM employees;
salary 컬럼에 NULL이 있으면, 그 행들은 그냥 무시되고 평균이 계산돼. 그래서 평균 연봉이 실제보다 높게 나올 수도 있어.
어떻게 피하지?
집계하기 전에 NULL을 기본값으로 바꿔줘야 해. 예를 들어 COALESCE()를 써봐:
SELECT AVG(COALESCE(salary, 0)) AS avg_salary
FROM employees;
이제 NULL 값이 0으로 바뀌어서 계산돼.
실수 3: NULL끼리 비교하기
DB에서 NULL은 진짜 아무것도 아니고, 심지어 다른 NULL이랑도 같지 않아. 이거 좀 당황스러울 수 있지.
무슨 일이 일어나냐면?
SELECT *
FROM students
WHERE NULL = NULL;
이 쿼리도 결과가 없어. 왜냐면 SQL은 없는 값이 다른 없는 값이랑 같을 수 없다고 생각하거든. 철학적이지?
그럼 어떻게 해야 하냐?
NULL 두 개가 "같은지" 확인하려면 IS NULL 같은 걸 써야 해. 예를 들면:
SELECT *
FROM students
WHERE first_name IS NULL AND last_name IS NULL;
실수 4: NULL로 나누기
NULL로 나누는 건 그냥 실수도 아니고, 수학적으로도 범죄(?)야. SQL은 결과를 NULL로 돌려줘.
무슨 일이 일어나냐면?
SELECT 10 / NULL AS result;
결과? NULL. SQL은 네가 뭘 원하는지 이해하려고도 안 해.
어떻게 피하지?
이런 실수를 막으려면 COALESCE()나 NULLIF()를 써봐:
SELECT 10 / COALESCE(divisor, 1) AS result
FROM calculations;
여기서 divisor가 NULL이면 1로 나누게 돼.
실수 5: NULL이랑 논리 연산자 쓰기
NULL이 논리 연산식에 들어가면 로직이 꼬여버려. 예를 들어 TRUE AND NULL은 TRUE나 FALSE가 아니라 NULL이 돼.
무슨 일이 일어나냐면?
SELECT *
FROM students
WHERE age > 18 OR age = NULL;
여기서 age > 18이 맞는 행이 있어도, age가 NULL인 행은 결과에서 빠질 수 있어. 왜냐면 age = NULL 부분이 NULL을 반환해서 TRUE가 아니거든.
그럼 어떻게 해야 하냐?
항상 논리 조건에서 NULL을 명확하게 처리해줘:
SELECT *
FROM students
WHERE age > 18 OR age IS NULL;
실수 6: NULL 정렬할 때의 암묵적 동작 (가장 "헤비"한 실수)
ORDER BY 쿼리에서 NULL이 어떻게 정렬되는지 생각보다 헷갈릴 수 있어. PostgreSQL에서는 오름차순이면 NULL이 맨 뒤, 내림차순이면 맨 앞에 와.
무슨 일이 일어나냐면?
SELECT product_name, price
FROM products
ORDER BY price;
price에 NULL이 있으면, 그 행들은 리스트 맨 뒤에 나와.
예상치 못한 결과를 피하려면?
NULLS FIRST나 NULLS LAST로 NULL 정렬 위치를 명확히 지정할 수 있어:
SELECT product_name, price
FROM products
ORDER BY price NULLS FIRST;
실수 7: 외래 키랑 NULL 같이 쓸 때의 문제
외래 키 컬럼에 NULL이 들어가면 가끔 예상 못한 일이 생길 수 있어.
무슨 일이 일어나냐면?
테이블에 외래 키를 추가하고, 외래 키 필드를 비워서 행을 넣으면 PostgreSQL은 아무 반응도 안 해. 왜냐면 NULL 값은 연결된 테이블에서 체크하지 않거든.
그럼 어떻게 해야 하냐?
이런 필드에 NULL이 들어가는 걸 막고 싶으면 NOT NULL 제약조건을 써. 아니면 그냥 NULL 값은 "고아"처럼 연결된 테이블에 속하지 않는다는 걸 기억해둬.
외래 키랑 연결된 테이블에 대해서는 다음 강의에서 더 자세히 다룰 거야 :P
GO TO FULL VERSION