MySQL에서 두 개의 SELECT 문 사이의 차이를 구하고 싶다면 서브쿼리(subquery)를 활용하는 것이 가장 간단한 방법입니다. 바깥쪽 쿼리에서 NOT IN 연산자와 함께 서브쿼리를 사용하면, 특정 조건에 해당하지 않는 레코드만 손쉽게 추출할 수 있습니다.
기본 문법
두 SELECT 결과의 차이를 구하는 기본적인 문법은 다음과 같습니다.
SELECT * FROM yourTableName WHERE yourColumnName NOT IN (SELECT yourColumnName FROM yourTableName WHERE yourCondition);
즉, 메인 쿼리는 전체 테이블을 대상으로 조회하되, 서브쿼리가 반환하는 값 목록에 포함되지 않은(NOT IN) 행들만 결과로 가져오게 됩니다.
예제 테이블 생성하기
문법을 실제로 이해하기 위해 예제 테이블을 먼저 만들어 보겠습니다. 테이블 생성 쿼리는 다음과 같습니다.
mysql> create table DifferenceSelectDemo
-> (
-> Id int NOT NULL AUTO_INCREMENT,
-> UserId int,
-> UserValue int,
-> PRIMARY KEY(Id)
-> );
Query OK, 0 rows affected (0.87 sec)위 쿼리는 자동 증가하는 Id를 기본 키로 가지며, UserId와 UserValue 두 개의 정수 컬럼을 포함하는 테이블을 생성합니다.
샘플 데이터 삽입하기
이제 INSERT 명령어를 사용해 몇 개의 레코드를 추가합니다.
mysql> insert into DifferenceSelectDemo(UserId,UserValue) values(10,10); Query OK, 1 row affected (0.24 sec) mysql> insert into DifferenceSelectDemo(UserId,UserValue) values(10,20); Query OK, 1 row affected (0.15 sec) mysql> insert into DifferenceSelectDemo(UserId,UserValue) values(20,30); Query OK, 1 row affected (0.17 sec) mysql> insert into DifferenceSelectDemo(UserId,UserValue) values(20,20); Query OK, 1 row affected (0.19 sec) mysql> insert into DifferenceSelectDemo(UserId,UserValue) values(30,40); Query OK, 1 row affected (0.14 sec) mysql> insert into DifferenceSelectDemo(UserId,UserValue) values(30,20); Query OK, 1 row affected (0.15 sec)
전체 레코드 조회하기
SELECT 문으로 테이블에 저장된 모든 레코드를 확인해 보겠습니다.
mysql> select *from DifferenceSelectDemo;
실행 결과는 다음과 같습니다.
+----+--------+-----------+ | Id | UserId | UserValue | +----+--------+-----------+ | 1 | 10 | 10 | | 2 | 10 | 20 | | 3 | 20 | 30 | | 4 | 20 | 20 | | 5 | 30 | 40 | | 6 | 30 | 20 | +----+--------+-----------+ 6 rows in set (0.02 sec)
총 6개의 레코드가 저장되어 있는 것을 확인할 수 있습니다.
두 SELECT 결과의 차이 구하기
이제 본격적으로 두 SELECT 문의 차이를 구하는 쿼리를 실행해 보겠습니다. 아래 예제에서는 Id = 1인 행의 UserValue(값 10)를 제외한 나머지 레코드를 조회합니다.
mysql> select *from DifferenceSelectDemo
-> WHERE UserValue NOT IN (select UserValue from DifferenceSelectDemo where Id=1);실행 결과는 다음과 같습니다.
+----+--------+-----------+ | Id | UserId | UserValue | +----+--------+-----------+ | 2 | 10 | 20 | | 3 | 20 | 30 | | 4 | 20 | 20 | | 5 | 30 | 40 | | 6 | 30 | 20 | +----+--------+-----------+ 5 rows in set (0.09 sec)
결과 분석
서브쿼리가 반환한 값은 Id=1 행의 UserValue인 10입니다. 따라서 메인 쿼리는 UserValue가 10이 아닌 모든 행을 반환하게 되며, 그 결과 첫 번째 행(Id=1) 하나가 제외된 5개의 레코드가 출력됩니다.
이처럼 NOT IN과 서브쿼리를 조합하면 두 SELECT 결과 집합 간의 차이를 간단하고 직관적으로 구할 수 있습니다. 참고로 NULL 값이 포함될 가능성이 있다면 NOT EXISTS나 LEFT JOIN ... IS NULL 방식을 사용하는 것이 더 안전하다는 점도 함께 기억해 두면 좋습니다.