메뉴 건너뛰기

tnt_db

Oracle NOT IN 의 함정

운영자 2002.09.17 20:27 조회 수 : 2627 추천:17

NOT IN 이라는 연산자는 IN 연산자의 반대 개념으로 사용된다.
IN 이라 하면 지정된 값중 하나라도 비교되는값과 같은 값이 있으면
TRUE를 RETURN 하는 연산자이다.
다음예제를 보자.

SCOTT.EMP 를 다음과 같이 읽어보자.

SELECT * FROM   EMP;

EMPNO      ENAME      JOB       MGR        HIREDATE             SAL        COMM       DEPTNO    
---------- ---------- --------- ---------- -------------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 80/12/17                    800                    20
      7499 ALLEN      SALESMAN        7698 81/02/20                   1600        300         30
      7521 WARD       SALESMAN        7698 81/02/22                   1250        500         30
      7566 JONES      MANAGER         7839 81/04/02                   2975                    20
      7654 MARTIN     SALESMAN        7698 81/09/28                   1250       1400         30
      7698 BLAKE      MANAGER         7839 81/05/01                   2850                    30
      7782 CLARK      MANAGER         7839 81/06/09                   2450                    10
      7788 SCOTT      ANALYST         7566 82/12/09                   3000                    20
      7839 KING       PRESIDENT            81/11/17                   5000                    10
      7844 TURNER     SALESMAN        7698 81/09/08                   1500          0         30
      7876 ADAMS      CLERK           7788 83/01/12                   1100                    20
      7900 JAMES      CLERK           7698 81/12/03                    950                    30
      7902 FORD       ANALYST         7566 81/12/03                   3000                    20
      7934 MILLER     CLERK           7782 82/01/23                   1300                    10
14 행이 선택되었습니다

이 중에서 MGR 이 7902 또는 7839 인 경우를 읽어오기위하여
다음과 같이 조건을 줄수 있을 것이다.

SELECT * FROM EMP
WHERE  MGR IN (7902,7839);

그러면 예상대로 4건의 RECORD가 끌려 나올것이다.

EMPNO      ENAME      JOB       MGR        HIREDATE             SAL        COMM       DEPTNO    
---------- ---------- --------- ---------- -------------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 80/12/17                    800                    20
      7566 JONES      MANAGER         7839 81/04/02                   2975                    20
      7698 BLAKE      MANAGER         7839 81/05/01                   2850                    30
      7782 CLARK      MANAGER         7839 81/06/09                   2450                

그렇다면 다음과 같은 조건을 생각해보자.
1.MGR 이 NULL 또는 7839 인 경우
그리고...
2.MGR 이 NULL 또는 7839 모두에 속하지 않는경우.

1의 경우를 위하여
조건을 다음과 같이 주면 될까?.

SELECT * FROM EMP
WHERE  MGR IN (NULL,7839);

결과를 보자..

EMPNO      ENAME      JOB       MGR        HIREDATE             SAL        COMM       DEPTNO    
---------- ---------- --------- ---------- -------------------- ---------- ---------- ----------
      7566 JONES      MANAGER         7839 81/04/02                   2975                    20
      7698 BLAKE      MANAGER         7839 81/05/01                   2850                    30
      7782 CLARK      MANAGER         7839 81/06/09                   2450                    10
3 행이 선택되었습니다

MGR이 NULL인 경우는 빠졌다..
왜 빠졌을까?.
위의 조건을 다시쓰면 다음과 같이 된다.
WHERE MGR = NULL OR MGR = 7839;

이렇게 되면 MGR=NULL 이란 조건은 항상 FALSE 로 RETURN 된다.
왜?..
NULL 은 항상 IS NULL 또는 IS NOT NULL 로 비교되어야 하기 때문이다.
따라서 MGR=7839 인 경우만이 검색된다.

그렇다면 2 의 경우는 어떻겠는가??.
즉, MGR NOT IN (NULL,7839) 이 경우.
NULL 과 7839 를 제외한 나머지 경우인 10건을 모두 검색할까?
아니면 NULL을 빠뜨리고 7839인 경우만을 제외한 11건을 검색할까?.
둘다 아니다..
한건도 검색하지 못한다.
NOT IN 연산자에 NULL 이 포함되면 어떠한 경우에도 한건도 DATA를 검색하지 못한다.
왜 그럴까??.
생각을 해보자 NOT IN 또한 IN 의 경우와 마찬가지다.
단지 지정된 값의 어느값이든 한 값이라도 같은 값이 있으면 TRUE가  되므로
AND 로 묶이게 된다는 것이 차이다.
다시 풀어서 쓰면 다음과 같이 된다.
WHERE MGR <> NULL AND MGR <> 7839;
1 의 경우는 OR로 연결되어 둘 중 한 조건만을 만족하면 되지만
이경우는 두 조건을 모두 만족시켜야 하므로 모든 RECORD가 MGR<>NULL 조건에 위배된다.
따라서 검색되는 행은 어느경우에도 없게된다.
IN의 경우는 예상을 하지만 NOT IN의 경우는 예상을 못하고 당하는 경우가 많아서
조심해야된다.
번호 제목 글쓴이 날짜 조회 수
46 빠진이빨찾기 II 운영자 2002.09.18 2973
45 빠진이빨찾기 운영자 2002.09.18 2872
44 순환참조에서의 상위코드로집계 운영자 2002.09.18 3150
43 CONNECT BY의 SORT와 JOIN 운영자 2002.09.18 2564
42 REPORT 양식맞추기4 운영자 2002.09.18 2411
41 REPORT 양식 맞추기 III 운영자 2002.09.18 2835
40 REPORT 양식 맞추기 II 운영자 2002.09.18 2601
39 REPORT 양식 맞추기 운영자 2002.09.18 31280
38 1:1 JOIN / 1:M JOIN 운영자 2002.09.18 2765
37 TUNING-01 운영자 2002.09.18 2537
36 소계와 합계 운영자 2002.09.18 3161
35 중복DATA 찾아내기 운영자 2002.09.17 2653
34 GROUP별 DATA 분류 운영자 2002.09.17 2852
33 PARAMETER값에 따라 변경이 일어나는 문장 운영자 2002.09.17 15661
32 SELF JOIN 운영자 2002.09.17 3197
31 Outer Join 운영자 2002.09.17 2758
30 HINTS (출처-Oracle8.0 Tuning Guide) 운영자 2002.09.17 2587
29 단일행 문자 함수 운영자 2002.09.17 2677
28 단일행 수치 함수 운영자 2002.09.17 2697
» NOT IN 의 함정 운영자 2002.09.17 2627
위로