본문 바로가기

Database/MySQL

[데이터베이스(강의)] 7. SQL로 데이터 조회 (NULL, three-valued logic)

 

 

 

* SQL에서 NULL의 의미

 - unknown                           _ 알려지지 않음

 - unavailable or withheld     _ 비공개 or 이용불가

 - not applicable                   _ 해당사항 없음

 

 


 

employee 테이블이 아래와 같을 때,

 

 

SELECT id FROM employee WHERE birth_date = NULL;

 

=> 조회할 수가 없다.

 

 

SELECT id FROM employee WHERE birth_date is NULL;

 

=> NULL 에 대해서는 IS / IS NOT 을 사용해야 한다.

 


 

* NULL과 Three - Valued Logic 

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

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

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

 

 


 

SELECT id FROM employee WHERE birth_date = '1990-11-05';

 

employee 테이블에서 birth_date가 위와 같은 데이터를 조회한다면

Null 과 비교한 결과는 True / False 가 아닌 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이라면?

 

ex)

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

 


 

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'

                 );

 

 

만일 dept_id 에 NULL이 하나라도 존재하는 경우에는 

내부 쿼리문 자체가 UNKNOWN을 반환하게 되어 (조건을 만족하는 튜플이 있음에도 불구하고)

최종적으로 SELECT문은 아무것도 반환하지 않는다.          birth_date >= '2000-01-01' 인 튜플이 있어도

 


 

방법1. dept_id가 NULL값을 가질 수 없도록 NOT NULL 제약을 걸어둔다.

 

 

방법2. WHERE절에 dept_id 가 NULL인 튜플을 포함하지 않도록 조건 추가.

           (쿼리의 리턴값이 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

                 );

 

 

방법3. WHERE절에 NOT EXISTS 사용.

 

SELECT D.id, D.name

FROM department D

WHERE NOT EXISTS 

                        SELECT *

                        FROM employee E

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

                                       AND E.dept_id = D.id

                 );

 


 

https://www.youtube.com/watch?v=y_7rOoOodCY&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=7