본문 바로가기
DB

7. MySQL 데이터 조회 - 3 (NULL)

by 유니개발 2023. 4. 29.

SQL에서 NULL의 의미

- unknown

- unavailable or withheld

- not applicable

 

비교연산자를 사용해서 NULL과 비교하면 안됨! 

값이 NULL인 attribute를 찾고 싶다면 IS 또는 IS NOT을 사용해야함.

- e.g. SELECT id FROM employee WHERE birth_date IS NULL;  O  (생일 table값이 NULL인 직원 id 출력)

         SELECT id FROM employee WHERE birth_date = NULL;  X  (출력안됨) (empty set 출력)

 

NULL과 SQL three-valued logic

- SQL에서 NULL과 비교 연산을 하게 되면 그 결과는 UNKNOWN

- UNKNOWN은 'TRUE 일수도 있고 FALSE일 수도 있다'는 의미

- three-valued logic : 비교/논리 연산의 결과로 TRUE, FALSE, UNKNOWN을 가짐

 

1 = NULL => UNKNOWN

1 != NULL => UNKNOWN

1 > NULL => UNKNOWN

1 <= NULL => UNKNOWN

NULL = NULL => UNKNOWN

 

NULL이라는 값이 실제로 어떤 유효한 값을 가질 수 있었다면, 그 값에 따라 이 결과들이 TURE이거나 FALSE일 수 있기

때문에 UNKNOWN으로 처리함.

 

UNKNOWN의 AND, OR, NOT 논리 연산

 

WHERE절의 condition(s) ★

- where절에 있는 condition(s)의 결과가 TRUE인 tuple(s)만 선택됨.

- 즉, 결과가 FALSE거나 UNKNOWN이면 tuple은 선택되지 않음.

 

NOT IN 사용시 주의사항

- v NOT IN (v1, v2, v3) => v != v1 AND v! = v2 AND v != v3 와 같은 의미

- 만약 v1, v2, v3 중에 하나가 NULL이라면 무조건 FALSE 이거나 UNKNOWN임

NOT IN 과 UNKNOWN 예제

만약

SELECT D.id, D.name

FROM department AS D

WHERE D.id NOT IN (

                     SELECT E.dept_id

                     FROM employee E

                     WHERE E.birth_date >= '2000-01-01'

             );

이 쿼리에서 아직 부서배치를 받지 않은(E.dept_id가 NULL인) 2000년생(E.birth_date >= '2000-01-01')이 있다면 D.id가 어떤 값이라고 할지라도 NOT IN subquery문에 의해서 (NULL 때문에) UNKNOWN이 되거나 FALSE가 됨 => WHERE절은 TRUE일 때만 반환하므로 반환되는 값이 없음 => 결국 SELECT문도 아무 값도 반환하지 못함

 

E.dept_id를 NOT NULL로 미리 설정을 하거나 subquery문의 WHERE E.birth_date >= '2000-01-01' 절을

WHERE E.birth_date >= '2000-01-01' AND E.dept_id IS NOT NULL 로 바꾸는 방법이 있음.

 

또한, IN과 EXISTS는 바꿔 쓸 수 있으므로

WHERE NOT EXISITS (

                     SELECT * 

                     FROM employee E

                     WHERE E.dept_id = D.id AND E.birth_date >= '2000-01-01'

             );

로 바꿀 수 있음.

 

댓글