MySQL에서는 Oracle 등 다른 DBMS에서 제공하는 MINUS(또는 EXCEPT) 연산자를 직접 사용할 수 없습니다. 하지만 LEFT JOIN과 IS NULL 조건을 조합하면 MINUS와 완전히 동일한 결과를 얻을 수 있습니다. 이러한 기법은 흔히 '안티 조인(Anti Join)'이라고 불리며, 두 테이블 간의 차집합을 구할 때 매우 유용합니다. 아래 예제를 통해 구체적인 방법을 살펴보겠습니다.
예제
이 예제에서는 다음과 같은 데이터를 가진 두 개의 테이블, 즉 Student_detail과 Student_info를 사용합니다.
mysql> Select * from Student_detail; +-----------+---------+------------+------------+ | studentid | Name | Address | Subject | +-----------+---------+------------+------------+ | 101 | YashPal | Amritsar | History | | 105 | Gaurav | Chandigarh | Literature | | 130 | Ram | Jhansi | Computers | | 132 | Shyam | Chandigarh | Economics | | 133 | Mohan | Delhi | Computers | | 150 | Rajesh | Jaipur | Yoga | | 160 | Pradeep | Kochi | Hindi | +-----------+---------+------------+------------+ 7 rows in set (0.00 sec) mysql> Select * from Student_info; +-----------+-----------+------------+-------------+ | studentid | Name | Address | Subject | +-----------+-----------+------------+-------------+ | 101 | YashPal | Amritsar | History | | 105 | Gaurav | Chandigarh | Literature | | 130 | Ram | Jhansi | Computers | | 132 | Shyam | Chandigarh | Economics | | 133 | Mohan | Delhi | Computers | | 165 | Abhimanyu | Calcutta | Electronics | +-----------+-----------+------------+-------------+ 6 rows in set (0.00 sec)
두 테이블을 비교해 보면, Student_info에는 존재하지만 Student_detail에는 없는 학번(studentid)이 하나 있고, 그 반대의 경우도 존재합니다. 이제 JOIN을 활용한 쿼리로 차집합을 구해 보겠습니다.
1. Student_info에만 있는 studentid 조회하기
아래 쿼리는 LEFT JOIN을 사용하여 MINUS를 시뮬레이션하며, Student_info 테이블에는 존재하지만 Student_detail 테이블에는 없는 'studentid' 값을 반환합니다.
mysql> SELECT studentid from student_info LEFT JOIN Student_detail USING(studentid) WHERE student_detail.studentid IS NULL; +-----------+ | studentid | +-----------+ | 165 | +-----------+ 1 row in set (0.07 sec)
쿼리의 동작 원리는 다음과 같습니다. 먼저 student_info를 기준으로 Student_detail을 LEFT JOIN하면, 일치하는 행이 없는 경우 오른쪽 테이블의 컬럼은 NULL로 채워집니다. 따라서 WHERE 절에서 student_detail.studentid IS NULL 조건을 적용하면, Student_detail에 짝이 없는 행, 즉 차집합에 해당하는 결과만 남게 됩니다.
2. Student_detail에만 있는 studentid 조회하기
반대로, 다음 쿼리는 위 쿼리와 정반대의 결과를 제공합니다. 즉, Student_detail 테이블에는 존재하지만 Student_info 테이블에는 없는 'studentid' 값을 반환합니다.
mysql> SELECT studentid from student_detail LEFT JOIN Student_info USING(studentid) WHERE student_info.studentid IS NULL; +-----------+ | studentid | +-----------+ | 150 | | 160 | +-----------+ 2 rows in set (0.00 sec)
이처럼 MySQL에서 MINUS 연산이 필요할 때는 기준 테이블을 LEFT JOIN의 왼쪽에 두고, 비교 대상 테이블의 키 값이 NULL인지 확인하는 방식으로 손쉽게 차집합을 구현할 수 있습니다. 참고로 MySQL 8.0.31부터는 표준 SQL의 EXCEPT 연산자가 지원되므로, 최신 버전을 사용한다면 EXCEPT를 직접 활용하는 것도 좋은 대안입니다.