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

MySQL에서 테이블 A와 비교해 테이블 B에 없는 데이터만 테이블 C에 삽입하는 방법

테이블 A의 데이터 중 테이블 B에는 존재하지 않는 레코드만 골라내어 테이블 C에 삽입하고 싶다면 LEFT JOINIS NULL 조건을 함께 사용하면 됩니다. 이 글에서는 세 개의 예제 테이블을 만들고, 실제 쿼리가 어떻게 동작하는지 단계별로 살펴보겠습니다.

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

먼저 demo20이라는 이름의 테이블을 생성합니다.

mysql> create table demo20
-> (
-> id int,
-> name varchar(20)
-> );
Query OK, 0 rows affected (1.87 sec)

INSERT 명령문으로 몇 개의 레코드를 삽입합니다.

mysql> insert into demo20 values(100,'John');
Query OK, 1 row affected (0.07 sec)

mysql> insert into demo20 values(101,'Bob');
Query OK, 1 row affected (0.24 sec)

mysql> insert into demo20 values(102,'Mike');
Query OK, 1 row affected (0.12 sec)

mysql> insert into demo20 values(103,'Carol');
Query OK, 1 row affected (0.15 sec)

SELECT 문으로 저장된 데이터를 확인합니다.

mysql> select *from demo20;

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

+------+-------+
| id   | name  |
+------+-------+
|  100 | John  |
|  101 | Bob   |
|  102 | Mike  |
|  103 | Carol |
+------+-------+
4 rows in set (0.00 sec)

2단계: 두 번째 테이블 생성 (테이블 B 역할)

이번에는 비교 대상이 될 demo21 테이블을 생성합니다.

mysql> create table demo21
-> (
-> id int,
-> name varchar(20)
-> );
Query OK, 0 rows affected (1.70 sec)

마찬가지로 레코드를 삽입합니다.

mysql> insert into demo21 values(100,'Sam');
Query OK, 1 row affected (0.12 sec)

mysql> insert into demo21 values(101,'Adam');
Query OK, 1 row affected (0.14 sec)

mysql> insert into demo21 values(133,'Bob');
Query OK, 1 row affected (0.13 sec)

mysql> insert into demo21 values(145,'David');
Query OK, 1 row affected (0.15 sec)

SELECT 문으로 데이터를 확인합니다.

mysql> select *from demo21;

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

+------+-------+
| id   | name  |
+------+-------+
|  100 | Sam   |
|  101 | Adam  |
|  133 | Bob   |
|  145 | David |
+------+-------+
4 rows in set (0.00 sec)

3단계: 세 번째 테이블 생성 (테이블 C 역할)

데이터를 최종적으로 삽입할 빈 테이블 demo22를 생성합니다.

mysql> create table demo22
-> (
-> id int,
-> name varchar(20)
-> );
Query OK, 0 rows affected (1.39 sec)

핵심 쿼리: B에 없는 데이터만 C에 삽입하기

이제 demo20을 테이블 A, demo21을 테이블 B, demo22를 테이블 C라고 가정하겠습니다. 아래 쿼리는 A(demo20)의 데이터 중 B(demo21)에 존재하지 않는 레코드만 골라 C(demo22)에 삽입합니다.

mysql> insert into demo22(id,name)
-> select tbl1.id,tbl1.name from demo20 tbl1
-> left join demo21 tbl2 on tbl2.id=tbl1.id
-> where tbl2.id is null;
Query OK, 2 rows affected (0.21 sec)
Records: 2 Duplicates: 0 Warnings: 0

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

mysql> select *from demo22;

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

+------+-------+
| id   | name  |
+------+-------+
|  102 | Mike  |
|  103 | Carol |
+------+-------+
2 rows in set (0.00 sec)

쿼리 동작 원리

이 쿼리가 의도대로 작동한 이유는 다음과 같습니다.

LEFT JOIN: 왼쪽 테이블(A)의 모든 행을 기준으로 오른쪽 테이블(B)과 id 값을 비교해 연결합니다. 이때 B에 일치하는 id가 없는 A의 행은 그대로 유지되며, B 쪽 컬럼 값은 NULL로 채워집니다.

WHERE tbl2.id IS NULL: 조인 결과 중 B 쪽 id가 NULL인 행, 즉 B에 존재하지 않는 A의 레코드만 필터링합니다.

INSERT INTO ... SELECT: 필터링된 결과를 바로 테이블 C에 삽입합니다.

예제에서 A에는 100(John), 101(Bob), 102(Mike), 103(Carol)이 있었고, B에는 100과 101이 존재했기 때문에 일치하지 않는 102(Mike)와 103(Carol)만 C에 삽입된 것입니다. 참고로 NOT EXISTS 서브쿼리나 NOT IN 절을 사용해도 같은 결과를 얻을 수 있지만, 대량의 데이터를 다룰 때는 적절한 인덱스와 함께 LEFT JOIN 방식이 성능 면에서 유리한 경우가 많습니다.