MySQL에서 전체 데이터를 조회할 때 특정 행만 제외하고 싶은 경우가 자주 있습니다. 이럴 때 하위 쿼리(Subquery)와 NOT IN 연산자를 함께 사용하면 간단하게 해결할 수 있습니다. 이번 글에서는 예제 테이블을 만들고, 하위 쿼리를 사용해 특정 행을 제외하는 방법을 단계별로 살펴보겠습니다.
1. 예제 테이블 생성
먼저 실습에 사용할 테이블을 생성합니다.
mysql> create table DemoTable
-> (
-> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> Name varchar(100),
-> Age int
-> );
Query OK, 0 rows affected (0.87 sec)
2. 샘플 데이터 삽입
INSERT 문을 사용해 몇 개의 레코드를 추가합니다.
mysql> insert into DemoTable(Name,Age) values('John',21);
Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable(Name,Age) values('Carol',22);
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable(Name,Age) values('David',23);
Query OK, 1 row affected (0.54 sec)
3. 전체 데이터 확인
SELECT 문으로 테이블의 모든 레코드를 조회해 보겠습니다.
mysql> select *from DemoTable;
실행 결과
+----+-------+------+ | Id | Name | Age | +----+-------+------+ | 1 | John | 21 | | 2 | Carol | 22 | | 3 | David | 23 | +----+-------+------+ 3 rows in set (0.00 sec)
4. 하위 쿼리로 특정 행 제외하기
이제 이름이 'Carol'인 행을 제외한 나머지 데이터를 조회해 보겠습니다. WHERE 절 안에 하위 쿼리를 넣고 NOT IN 연산자와 결합하면 됩니다.
mysql> select *from DemoTable
-> where Name not in (select Name from DemoTable where Name='Carol'
-> );
실행 결과
+----+-------+------+ | Id | Name | Age | +----+-------+------+ | 1 | John | 21 | | 3 | David | 23 | +----+-------+------+ 2 rows in set (0.00 sec)
동작 원리 정리
위 쿼리는 다음과 같은 순서로 동작합니다.
- 하위 쿼리 실행: 내부의 SELECT 문이 먼저 실행되어 'Carol'이라는 이름을 반환합니다.
- NOT IN 필터링: 외부 쿼리는 Name 값이 하위 쿼리 결과에 포함되지 않는 행만 선택합니다.
- 결과 반환: 'Carol' 행이 제외된 John과 David의 레코드만 출력됩니다.
참고 사항
NOT IN을 사용할 때는 하위 쿼리 결과에 NULL 값이 포함되지 않도록 주의해야 합니다. NULL이 포함되면 비교 결과가 항상 UNKNOWN이 되어 의도하지 않게 아무 행도 반환되지 않을 수 있습니다. 이 경우 NOT EXISTS나 LEFT JOIN 방식을 대안으로 고려하는 것이 좋습니다.