기주

[DB] SQL에서 NULL의 의미와 three-valued logic에 대해 알아보기 본문

DBMS/데이터베이스 이론

[DB] SQL에서 NULL의 의미와 three-valued logic에 대해 알아보기

기주그지마 2025. 1. 14. 21:01

 

NULL의 의미와 three-valued logic에 대해 알아보기

 


SQL에서 NULL의 의미



1.unknown
(실제로 값이 있으나)알려지지 않은.

ex)

알려지지않은 생일


2.unavailable or withheld
이용할 수 없는.

ex)

민감한 개인정보

3. Not applicable
해당사항이 없는.

ex)

전화기가 없는 집의 전화번호






NULL값은 = 연산자를 사용할 수 없다

IS / IS NOT 연산자를 사용해야한다.



SQL에서 NULL과 비교 연산(=,!=, <,>,)을 하게되면 그 결과는 UNKNOWN이다.

UNKNOWN은 true일수도 있고 false일 수도 있다는 의미이다.

 

NULL이 유효한 값을 갖게되었을 때 그 값에 따라 결과가 달라질 수 있기 때문이다.


 

Three-valed logic

비교/논리 연산의 결과(=,!=,>,<)로 TRUE, FALSE, UNKNOWN을 가진다

 

1 = NULL       => UNKNOWN
1 != NULL      => UNKNOWN
1 > NULL       => UNKNOWN
1 <= NULL      => UNKNOWN
NULL = NULL    => UNKNOWN


전부 UNKNOWN 반환
왜? NULL이 유효한 값을 갖게되었을 때 그 값에 따라 결과가 달라질 수 있기 때문이다.


True AND UNKNOWN     => UNKNOWN

UNKNOWN AND UNKNOWN  => UNKNOWN

FALSE OR UNKNOWN     => UNKNOWN

UNKNOWN OR UNKNOWN   => UNKNOWN

NOT UNKNOWN          => UNKNOWN


UNKNOWN의 값에따라 true가될 수도, FALSE가 될 수도있는 연산이라면 모두 UNKNOWN을 반환한다.

 

UNKNOWN의 값에 상관없이 결과가 무조건 결정되어있다면 그 값을 반환한다

 

ex)

FALSE AND UKNOWN => FALSE

TRUE OR UKNOWN => TRUE



WHERE절의 condition의 결과가 TRUE인 튜플만 선택된다

**즉, 결과가 FALSE거나 UNKNOWN이면 튜플은 선택되지 않는다



NOT IN 사용시 주의사항

V NOT IN(v1,v2,v3)의 의미는 다음과 같다

v != v1 AND v != v2 AND v != v3



만약 v1,v2,v3중에 하나가 NULL이라면?

3 NOT IN (1,2,4) => true

3 NOT IN (1,2,3) => FALSE

3 NOT IN (1,3,NULL) => FALSE

3 NOT IN (1,2,NULL) => UNKNOWN

 

 



Q. 2000년대생이 없는 부서의 ID와 이름을 알고싶다

SELECT D.id, D.name
FROM department D
WHERE D.id NOT IN (SELECT E.dept_id
                  FROM employee E
                  WHERE E.birth_date >= '2000-01-01');



NOT IN() 안에 NULL값이 있다면 높은확률로 WHERE문에서 UNKNOWN을 반환한다.
이때 WHERE문은 true일때만 데이터를 가져오므로, 실제로 2000년대생이 없는 부서라고해도, 어떤 데이터도 가져오지 않는 문제가 생길 수 있다.




이를 해결하기 위한 방법
1.서브쿼리에 조건 추가
AND E.dept_id IS NOT NULL

SELECT D.id, D.name
FROM department D
WHERE D.id NOT IN (SELECT E.dept_id
                   FROM employee E
                   WHERE E.birth_date >= '2000-01-01'
                   AND E.dept_id IS NOT NULL);




2.NOT IN을 NOT EXISTS로 교체

SELECT D.id, D.name
FROM department D
WHERE D.id NOT EXISTS (SELECT E.dept_id
                       FROM employee E
                       WHERE E.birth_date >= '2000-01-01'
                       AND E.dept_id IS NOT NULL);