MySQL NOT IN 검색 조건 NULL 주의점

MySQL에서 검색 조건을 사용할때 IN 또는 NOT IN을 많이 사용합니다.

IN 또는 NOT IN에 고정값을 넣어서 사용하는 경우가 많습니다.

또는 고정값 대신에 서브 쿼리를 사용해서 작성하는 경우도 있습니다.

NOT IN에 서브쿼리를 사용해 결과를 취득하는 경우에 주의점이 있습니다.

바로 NULL입니다.

검색 조건으로 사용한 컬럼에 NULL이 존재하는 경우에는 원하는 결과를 얻을수 없는 경우도 있습니다.

샘플 데이터를 사용해 확인해보겠습니다.

Member란 테이블에 아래와 같은 데이터를 준비했습니다.

mysql> SELECT * FROM Member;
+----+----------+-------+------+---------+
| id | Memberid | name  | age  | company |
+----+----------+-------+------+---------+
|  1 |        1 | tom   |   24 | A       |
|  2 |        2 | cat   |   36 | A       |
|  3 |        3 | work  |   29 | C       |
|  4 |        4 | bench |   45 | A       |
|  5 |        5 | post  |   59 | B       |
|  6 |        6 | gre   |   21 | C       |
|  7 |        8 | php   |   23 | NULL    |
|  8 |        9 | da    |   61 | NULL    |
|  9 |        7 | jang  |   36 | E       |
+----+----------+-------+------+---------+
9 rows in set (0.00 sec)

 

Complate란 테이블에는 아래와 같은 데이터를 준비했습니다.

mysql> SELECT * FROM Complate;
+----+----------+-------+---------+
| id | Memberid | price | payment |
+----+----------+-------+---------+
|  1 |        1 |  1000 | card    |
|  2 |        2 |  2000 | card    |
|  3 |        4 |  1500 | cash    |
|  4 |        6 |   300 | card    |
|  5 |        2 |  3000 | NULL    |
|  6 |        6 |   100 | NULL    |
|  7 |        1 |  3000 | cash    |
|  8 |     NULL |   500 | card    |
|  9 |        4 |   330 | cash    |
+----+----------+-------+---------+
9 rows in set (0.00 sec)

 

Complate테이블의 Memberid에 존재하는 값만 Member테이블에서 취득하도록 NOT IN에 서브쿼리를 사용해 취득하겠습니다.

SELECT *
FROM Member AS m
WHERE m.Memberid NOT IN
        (SELECT Memberid
         FROM Complate);

 

결과

Empty set (0.00 sec)

 

취득한 결과값이 0건입니다.

Complate테이블의 MemberidNULL값이 존재하기 때문에 결과를 제대로 취득하지 못했습니다.

NOT IN에 서브 쿼리를 사용하는 경우에는 검색 조건에 해당하는 컬럼에 NULL값이 있는지 확인을 하고 사용해야합니다.

NULL값이 존재하는 경우에는 서브 쿼리에서 NULL은 제외하도록 지정해 사용하는 것이 좋습니다.

SELECT *
FROM Member AS m
WHERE m.Memberid NOT IN
       (SELECT Memberid
       FROM Complate
       WHERE Memberid IS NOT NULL);

 

결과

+----+----------+------+------+---------+
| id | Memberid | name | age  | company |
+----+----------+------+------+---------+
|  3 |        3 | work |   29 | C       |
|  5 |        5 | post |   59 | B       |
|  7 |        8 | php  |   23 | NULL    |
|  8 |        9 | da   |   61 | NULL    |
|  9 |        7 | jang |   36 | E       |
+----+----------+------+------+---------+
5 rows in set (0.00 sec)

 

또는 NOT EXISTSLEFT JOIN을 사용해 취득하는 방법도 있습니다.

댓글