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

MySQL에서 한 테이블에는 존재하지 않고 다른 테이블에만 있는 레코드 찾는 방법

MySQL에서 한 테이블의 데이터 중 다른 테이블에는 존재하지 않는 레코드를 찾아야 하는 경우가 자주 있습니다. 이럴 때 서브쿼리(subquery)NOT IN 연산자를 활용하면 간단하게 해결할 수 있습니다. 아래 예제를 통해 단계별로 살펴보겠습니다.

1. 첫 번째 테이블 생성하기

먼저 CREATE 명령어를 사용해 'PresentHistory'라는 이름의 테이블을 생성합니다. 이 테이블은 두 개의 컬럼을 가지고 있습니다.

mysql> CREATE table PresentHistory
-> (
-> HisID int,
-> HisName varchar(100)
-> );
Query OK, 0 rows affected (0.54 sec)

2. 첫 번째 테이블에 데이터 삽입

테이블 생성 후 INSERT 명령어를 사용해 두 번째 테이블에도 존재할 레코드들을 삽입합니다.

mysql> INSERT into PresentHistory values(1,'John');
Query OK, 1 row affected (0.13 sec)

mysql> INSERT into PresentHistory values(2,'Bob');
Query OK, 1 row affected (0.15 sec)

데이터가 정상적으로 입력되었는지 SELECT 문으로 확인해 보겠습니다.

mysql> SELECT * from PresentHistory;

위 쿼리를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

+-------+---------+
| HisID | HisName |
+-------+---------+
| 1     | John    |
| 2     | Bob     |
+-------+---------+
2 rows in set (0.00 sec)

3. 두 번째 테이블 생성 및 데이터 삽입

이번에는 CREATE 명령어로 'PastHistory'라는 두 번째 테이블을 만듭니다. 역시 두 개의 컬럼으로 구성됩니다.

mysql> CREATE table PastHistory
-> (
-> PastId int,
-> PastName varchar(100)
-> );
Query OK, 0 rows affected (0.74 sec)

테이블을 만든 뒤, 첫 번째 테이블에도 존재하는 레코드 2개와 존재하지 않는 레코드 2개를 함께 삽입합니다.

mysql> INSERT into PastHistory values(1,'John');
Query OK, 1 row affected (0.13 sec)

mysql> INSERT into PastHistory values(2,'Bob');
Query OK, 1 row affected (0.13 sec)

mysql> INSERT into PastHistory values(3,'Carol');
Query OK, 1 row affected (0.17 sec)

mysql> INSERT into PastHistory values(4,'Jason');
Query OK, 1 row affected (0.16 sec)

현재 두 번째 테이블에는 총 4개의 레코드가 있으며, 그중 2개는 첫 번째 테이블과 동일하고 나머지 2개는 첫 번째 테이블에 없는 데이터입니다. SELECT 문으로 확인해 보겠습니다.

mysql> SELECT * from PastHistory;

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

+--------+----------+
| PastId | PastName |
+--------+----------+
| 1      | John     |
| 2      | Bob      |
| 3      | Carol    |
| 4      | Jason    |
+--------+----------+
4 rows in set (0.00 sec)

4. NOT IN 서브쿼리로 차집합 구하기

한 테이블에는 없지만 다른 테이블에는 존재하는 레코드를 조회하는 기본 문법은 다음과 같습니다.

SELECT * from yourSecondTableName where columnNamefromSecondtable NOT IN
(SELECT columnNamefromfirsttable from yourFirstTableName);

이 문법을 실제 예제에 적용하여, 두 번째 테이블(PastHistory) 중 첫 번째 테이블(PresentHistory)에 없는 고유한 레코드만 조회해 보겠습니다.

mysql> SELECT * from PastHistory where PastName not in (select HisName from
PresentHistory);

위 쿼리의 실행 결과는 다음과 같습니다.

+--------+----------+
| PastId | PastName |
+--------+----------+
| 3      | Carol    |
| 4      | Jason    |
+--------+----------+
2 rows in set (0.00 sec)

결과 분석

출력 결과를 보면 'Carol'과 'Jason'이라는 두 개의 레코드가 반환되었습니다. 이는 첫 번째 테이블인 PresentHistory에는 존재하지 않고 오직 PastHistory 테이블에만 있는 데이터입니다. 이처럼 NOT IN 연산자와 서브쿼리를 조합하면 두 테이블 간의 차집합을 손쉽게 구할 수 있습니다.

참고: 대량의 데이터를 다룰 때는 NOT IN보다 LEFT JOIN ... IS NULL 방식이나 NOT EXISTS 절을 사용하는 것이 성능 면에서 더 유리할 수 있습니다. 상황에 맞게 적절한 방법을 선택하시기 바랍니다.