Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL에서 테이블 B에 존재하지 않는 테이블 A의 데이터만 조회하는 방법 (NOT IN 활용)

NOT IN 연산자로 두 테이블의 차집합 조회하기

MySQL에서 한 테이블에는 존재하지만 다른 테이블에는 없는 데이터를 추출해야 하는 경우가 자주 있습니다. 예를 들어 전체 회원 목록에서 이미 탈퇴한 회원을 제외하거나, 재고 목록에서 판매된 상품을 걸러내는 작업이 대표적입니다. 이럴 때 NOT IN 연산자와 서브쿼리를 함께 사용하면 간단하게 해결할 수 있습니다.

이번 글에서는 실제 예제를 통해 테이블 A에는 있지만 테이블 B에는 없는 값만 조회하는 방법을 단계별로 살펴보겠습니다.

1단계: 첫 번째 테이블(A) 생성

먼저 비교 기준이 되는 테이블 A를 생성합니다. 아래 쿼리는 정수형 컬럼 하나를 가진 간단한 테이블입니다.

mysql> create table A
-> (
-> Value int
-> );
Query OK, 0 rows affected (0.56 sec)

2단계: 테이블 A에 데이터 삽입

INSERT 명령어를 사용해 테이블 A에 여러 개의 레코드를 추가합니다.

mysql> insert into A values(10);
Query OK, 1 row affected (0.23 sec)
mysql> insert into A values(20);
Query OK, 1 row affected (0.11 sec)
mysql> insert into A values(30);
Query OK, 1 row affected (0.11 sec)
mysql> insert into A values(50);
Query OK, 1 row affected (0.10 sec)
mysql> insert into A values(80);
Query OK, 1 row affected (0.12 sec)

3단계: 테이블 A의 전체 데이터 확인

SELECT 문으로 테이블 A에 저장된 모든 레코드를 조회해 보겠습니다.

mysql> select *from A;

실행 결과는 다음과 같습니다.

+-------+
| Value |
+-------+
| 10 |
| 20 |
| 30 |
| 50 |
| 80 |
+-------+
5 rows in set (0.00 sec)

총 5개의 값(10, 20, 30, 50, 80)이 저장되어 있습니다.

4단계: 두 번째 테이블(B) 생성 및 데이터 삽입

이번에는 비교 대상이 되는 테이블 B를 생성합니다.

mysql> create table B
-> (
-> Value2 int
-> );
Query OK, 0 rows affected (0.65 sec)

테이블 B에도 레코드를 삽입합니다.

mysql> insert into B values(20);
Query OK, 1 row affected (0.11 sec)
mysql> insert into B values(50);
Query OK, 1 row affected (0.15 sec)

SELECT 문으로 테이블 B의 내용을 확인합니다.

mysql> select *from B;

실행 결과는 다음과 같습니다.

+--------+
| Value2 |
+--------+
| 20 |
| 50 |
+--------+
2 rows in set (0.00 sec)

테이블 B에는 20과 50이라는 두 개의 값이 들어 있습니다.

5단계: NOT IN으로 테이블 B에 없는 값 조회하기

이제 핵심 쿼리입니다. 서브쿼리로 테이블 B의 값을 가져오고, NOT IN 연산자로 그 값들에 해당하지 않는 테이블 A의 레코드만 선택합니다.

mysql> SELECT * FROM A WHERE Value NOT IN (SELECT Value2 FROM B);

실행 결과는 다음과 같습니다.

+-------+
| Value |
+-------+
| 10 |
| 30 |
| 80 |
+-------+
3 rows in set (0.00 sec)

테이블 A의 5개 값 중 테이블 B에도 존재하는 20과 50이 제외되고, 나머지 10, 30, 80 세 개의 레코드만 반환된 것을 확인할 수 있습니다.

참고: NOT EXISTS를 활용한 대안

데이터 양이 많은 테이블에서는 NOT EXISTS 조인 방식이 더 나은 성능을 보일 수 있습니다. 특히 서브쿼리 결과에 NULL 값이 포함될 가능성이 있다면 NOT IN은 의도치 않게 빈 결과를 반환할 수 있으므로 주의가 필요합니다.

mysql> SELECT * FROM A
-> WHERE NOT EXISTS
-> (SELECT Value2 FROM B WHERE B.Value2 = A.Value);

두 방식 모두 동일한 결과(10, 30, 80)를 반환하지만, 대용량 데이터 처리 시에는 인덱스 설정 여부와 함께 NOT EXISTS 방식을 검토해 보는 것이 좋습니다.

정리

지금까지 NOT IN 연산자와 서브쿼리를 이용해 한 테이블에는 존재하지만 다른 테이블에는 없는 데이터를 조회하는 방법을 알아보았습니다. 핵심 문법은 SELECT * FROM A WHERE 컬럼 NOT IN (SELECT 컬럼 FROM B) 형태이며, NULL 처리와 성능이 중요한 환경에서는 NOT EXISTS를 대안으로 고려하면 됩니다.