특정 필드에 해당 값이 존재하지 않는 레코드를 조회하려면 WHERE 절과 함께 서브쿼리(subquery)를 사용하면 됩니다. 이번 글에서는 하나의 MySQL 쿼리 안에 두 개의 SELECT 문을 활용하여, 특정 조건에 해당하지 않는 레코드를 추출하는 방법을 예제와 함께 살펴보겠습니다.
1. 테이블 생성하기
먼저 예제에 사용할 테이블을 생성합니다. 사용자 이름과 사용자 유형(ENUM 타입)을 저장하는 간단한 구조입니다.
mysql> create table DemoTable1840
(
UserName varchar(20),
UserType ENUM('GUEST','ADMIN')
);
Query OK, 0 rows affected (0.00 sec)2. 샘플 데이터 삽입하기
INSERT 명령어를 사용해 몇 개의 레코드를 추가합니다.
mysql> insert into DemoTable1840 values('Chris','Admin');
Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1840 values('David','Guest');
Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1840 values('Chris','Guest');
Query OK, 1 row affected (0.00 sec)3. 전체 레코드 확인하기
SELECT 문으로 테이블의 모든 데이터를 조회해 보겠습니다.
mysql> select * from DemoTable1840;
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
+----------+----------+ | UserName | UserType | +----------+----------+ | Chris | ADMIN | | David | GUEST | | Chris | GUEST | +----------+----------+ 3 rows in set (0.00 sec)
현재 테이블에는 'Chris'가 ADMIN과 GUEST로 각각 한 번씩 저장되어 있고, 'David'는 GUEST로만 저장되어 있습니다.
4. 특정 필드에 값이 없는 레코드 조회하기
이제 핵심 쿼리입니다. NOT IN 연산자와 서브쿼리를 결합하면, ADMIN 유형으로 등록되지 않은 사용자만 손쉽게 추출할 수 있습니다.
mysql> select UserName from DemoTable1840 where UserName NOT IN(select UserName from DemoTable1840 where UserType='Admin');
실행 결과는 다음과 같습니다.
+----------+ | UserName | +----------+ | David | +----------+ 1 row in set (0.00 sec)
결과 분석
서브쿼리가 먼저 실행되어 UserType이 'Admin'인 사용자 목록, 즉 'Chris'를 반환합니다. 그런 다음 외부 쿼리는 전체 사용자 중 이 목록에 포함되지 않은(NOT IN) 사용자만 남기게 됩니다. 따라서 최종 결과에는 'David'만 출력됩니다.
이처럼 단일 쿼리 내에서 두 개의 SELECT 문을 조합하면, 별도의 임시 테이블이나 여러 단계의 쿼리 없이도 원하는 조건의 레코드를 효율적으로 필터링할 수 있습니다. 참고로 데이터 양이 많아질 경우 성능상의 이유로 LEFT JOIN ... IS NULL 방식 또는 NOT EXISTS 절을 대안으로 고려해 보는 것도 좋습니다.