이 블로그 검색

[RDB공통] NULL과 IN, EXISTS 차이

예시로 보는 NULL과 IN, EXISTS 차이.

설명은 봤으나 실제적으로 왜 연산 결과가 다른지에 대한 의문감이 계속 있을 분들을 위한 글.

[상황]

아래와 같은 T1, T2 테이블이 존재.




[IN]

select * from t1 where c2 in (select c2 from t2) ;

결과 :



이유 :

IN의 의미 : T1.C2에 각 값을 대입하여 (T1.C2='A' OR T1.C2=NULL OR T1.C2='B') 가 TRUE인 경우를 결과집합에 포함한다.

NULL='A', NULL=NULL 등의 NULL 연산의 결과는 항상 NULL, 즉 FALSE 이므로 C2가 NULL인 경우는 결과집합에 나타나지 않는다.


[NOT IN]

SQL :

select * from t1 where c2 not in (select c2 from t2) ;

결과 :

EMPTY SET (결과 값 없음)

이유 :

NOT IN의 의미 : T1.C2에 각 값을 대입하여 (T1.C2<>'A' AND T1.C2<>NULL AND T1.C2<>'B') 가 TRUE인 경우를 결과집합에 포함한다.

AND절에서 NULL연산으로 인한 FALSE가 발생하므로 모든 결과가 FALSE가 된다.

※ 모든 조건에 만족(TRUE)하는 경우에만 값이 나오는 AND 조건인데,

C2에 어떤 값을 대입하든 NULL과 연산하는 순간 FALSE가 되므로 모두 FALSE가 된다.


[EXISTS]

select * from t1 where exists (select 1 from t2 where t1.c2=t2.c2) ;

결과 :



이유 :

EXISTS의 의미 : 각 값을 대입하여 TRUE인 경우 결과집합에 포함한다.

T1.C2:='A' : T2.C2에 A가 있는지 확인. A가 있으므로 TRUE. (O)

T1.C2:=NULL : T2.C2에 NULL이 있는지 확인. NULL은 연산이 안되므로 FALSE. (X)

T1.C2:='B' : T2.C2에 B가 있는지 확인. B가 있으므로 TRUE. (O)

T1.C2:='C' : T2.C2에 C가 있는지 확인. C가 없으므로 FALSE. (X)


[NOT EXISTS]

select * from t1 where not exists (select 1 from t2 where t1.c2=t2.c2) ;

결과 :



이유 :

EXISTS의 의미 : 각 값을 대입하여 FALSE인 경우 결과집합에 포함한다.

T1.C2:='A' : T2.C2에 A가 있는지 확인. A가 있으므로 TRUE. (X)

T1.C2:=NULL : T2.C2에 NULL이 있는지 확인. NULL은 연산이 안되므로 FALSE. (O)

T1.C2:='B' : T2.C2에 B가 있는지 확인. B가 있으므로 TRUE. (X)

T1.C2:='C' : T2.C2에 C가 있는지 확인. C가 없으므로 FALSE. (O)

추천 게시글

[ORACLE] Data Pump가 느리거나 멈춘경우.

목록