개요
MySQL에서 중복된 값이 여러 개 있을 때, 특정 조건에 해당하는 레코드를 제외한 나머지 중에서 고유한(단일) 값을 찾아야 하는 경우가 있습니다. 이럴 때 NOT IN 연산자와 서브쿼리를 함께 사용하면 간단하게 해결할 수 있습니다.
이번 글에서는 예제 테이블을 만들고, NOT IN을 활용해 원하는 결과를 조회하는 방법을 단계별로 살펴보겠습니다.
1. 테이블 생성하기
먼저 예제로 사용할 테이블을 생성합니다.
mysql> create table DemoTable
(
Id int,
FirstName varchar(100)
);
Query OK, 0 rows affected (0.69 sec)2. 데이터 삽입하기
INSERT 명령어를 사용해 테이블에 샘플 데이터를 입력합니다. Id 컬럼에는 의도적으로 중복된 값(100, 101, 210)을 넣었습니다.
mysql> insert into DemoTable values(100,'Chris'); Query OK, 1 row affected (0.14 sec) mysql> insert into DemoTable values(100,'Robert'); Query OK, 1 row affected (0.48 sec) mysql> insert into DemoTable values(100,'Mike'); Query OK, 1 row affected (0.23 sec) mysql> insert into DemoTable values(100,'Sam'); Query OK, 1 row affected (0.48 sec) mysql> insert into DemoTable values(101,'David'); Query OK, 1 row affected (0.19 sec) mysql> insert into DemoTable values(101,'Robert'); Query OK, 1 row affected (0.44 sec) mysql> insert into DemoTable values(210,'Chris'); Query OK, 1 row affected (0.14 sec) mysql> insert into DemoTable values(210,'Bob'); Query OK, 1 row affected (0.17 sec) mysql> insert into DemoTable values(210,'Sam'); Query OK, 1 row affected (0.17 sec)
3. 전체 데이터 확인하기
SELECT 문으로 테이블의 모든 레코드를 조회해 보겠습니다.
mysql> select *from DemoTable;
실행 결과는 다음과 같습니다.
+------+-----------+ | Id | FirstName | +------+-----------+ | 100 | Chris | | 100 | Robert | | 100 | Mike | | 100 | Sam | | 101 | David | | 101 | Robert | | 210 | Chris | | 210 | Bob | | 210 | Sam | +------+-----------+ 9 rows in set (0.00 sec)
4. NOT IN으로 조건 제외 후 고유 값 조회하기
이제 핵심 쿼리입니다. FirstName이 'Chris'인 레코드가 포함된 Id를 서브쿼리로 추출한 뒤, NOT IN으로 해당 Id들을 제외하면 원하는 결과만 남게 됩니다.
mysql> select distinct Id from DemoTable where Id not in ( select Id from DemoTable where FirstName='Chris' );
위 쿼리는 다음과 같은 출력을 생성합니다.
+------+ | Id | +------+ | 101 | +------+ 1 row in set (0.08 sec)
결과 분석
'Chris'라는 이름은 Id 100과 Id 210에 포함되어 있습니다. 따라서 NOT IN 조건에 의해 이 두 Id는 제외되고, 'Chris'가 없는 유일한 Id인 101만 결과로 반환됩니다.
핵심 포인트 정리
- DISTINCT: 중복된 Id 값을 하나로 묶어 고유한 값만 반환합니다.
- NOT IN + 서브쿼리: 특정 조건(여기서는 FirstName = 'Chris')에 해당하는 레코드의 Id를 동적으로 제외합니다.
- 이 방식은 조건이 변경되어도 서브쿼리의 WHERE 절만 수정하면 되므로 유연하게 활용할 수 있습니다.
이처럼 NOT IN 연산자와 DISTINCT를 조합하면, 특정 조건을 만족하는 그룹을 손쉽게 배제하고 나머지 고유 값만 효율적으로 조회할 수 있습니다.