MySQL의 EXISTS 연산자는 서브쿼리의 결과 집합에 행이 존재하는지 여부를 검사하는 데 사용됩니다. 서브쿼리에서 조건에 맞는 행이 하나라도 발견되면 EXISTS는 TRUE를 반환하고, 반대로 NOT EXISTS는 FALSE를 반환합니다. 이 두 연산자는 주로 두 테이블 간의 관계를 확인하거나 특정 조건을 만족하는 레코드의 유무를 판별할 때 매우 유용합니다.
예제용 테이블 소개
EXISTS와 NOT EXISTS의 동작 방식을 이해하기 위해 'Cars', 'Customers', 'Reservations' 세 개의 테이블을 사용해 보겠습니다. 각 테이블에는 다음과 같은 데이터가 들어 있습니다.
mysql> Select * from Cars; +------+--------------+---------+ | ID | Name | Price | +------+--------------+---------+ | 1 | Nexa | 750000 | | 2 | Maruti Swift | 450000 | | 3 | BMW | 4450000 | | 4 | VOLVO | 2250000 | | 5 | Alto | 250000 | | 6 | Skoda | 1250000 | | 7 | Toyota | 2400000 | | 8 | Ford | 1100000 | +------+--------------+---------+ 8 rows in set (0.02 sec) mysql> Select * from Customers; +-------------+----------+ | Customer_Id | Name | +-------------+----------+ | 1 | Rahul | | 2 | Yashpal | | 3 | Gaurav | | 4 | Virender | +-------------+----------+ 4 rows in set (0.00 sec) mysql> Select * from Reservations; +------+-------------+------------+ | ID | Customer_id | Day | +------+-------------+------------+ | 1 | 1 | 2017-12-30 | | 2 | 2 | 2017-12-28 | | 3 | 2 | 2017-12-29 | | 4 | 1 | 2017-12-25 | | 5 | 3 | 2017-12-26 | +------+-------------+------------+ 5 rows in set (0.00 sec)
EXISTS 연산자 사용 예제
다음은 위 테이블들을 활용하여 EXISTS 연산자를 서브쿼리와 함께 사용한 예입니다.
mysql> Select Name from customers WHERE EXISTS (SELECT * FROM Reservations WHERE Customers.customer_id = Reservations.customer_id); +---------+ | Name | +---------+ | Rahul | | Yashpal | | Gaurav | +---------+ 3 rows in set (0.06 sec)
이 쿼리는 예약 기록이 있는 고객의 이름만 조회합니다. Customers 테이블의 각 행에 대해 서브쿼리가 Reservations 테이블에서 일치하는 customer_id를 찾으면 EXISTS가 TRUE를 반환하여 해당 고객이 결과에 포함됩니다. 따라서 예약을 한 적 있는 Rahul, Yashpal, Gaurav 세 명만 출력된 것을 확인할 수 있습니다.
NOT EXISTS 연산자 사용 예제
반대로 NOT EXISTS 연산자를 사용하면 예약 기록이 없는 고객을 찾을 수 있습니다.
mysql> Select Name from customers WHERE NOT EXISTS (SELECT * FROM Reservations WHERE Customers.customer_id = Reservations.customer_id); +----------+ | Name | +----------+ | Virender | +----------+ 1 row in set (0.04 sec)
이 쿼리는 예약 기록이 전혀 없는 고객의 이름을 반환합니다. 서브쿼리에서 일치하는 행을 찾지 못하면 NOT EXISTS가 TRUE가 되어 해당 고객이 결과 집합에 포함됩니다. 결과적으로 Virender 한 명만 조회되었습니다.
정리 및 활용 팁
- EXISTS: 서브쿼리 결과에 행이 하나라도 존재하면 TRUE를 반환하므로, 관련 데이터가 있는 레코드를 필터링할 때 사용합니다.
- NOT EXISTS: 서브쿼리 결과에 일치하는 행이 없을 때 TRUE를 반환하므로, 누락된 데이터나 미등록 레코드를 찾는 데 적합합니다.
- EXISTS 연산자는 실제 값이 아닌 존재 여부만 확인하기 때문에 서브쿼리에서
SELECT *대신 어떤 열을 선택해도 성능에는 영향을 주지 않습니다. - 대량의 데이터를 다룰 때는 LEFT JOIN + IS NULL 방식보다 NOT EXISTS가 더 직관적이고 경우에 따라 더 나은 성능을 보일 수 있습니다.