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

MySQL에서 하위 쿼리(NOT IN)를 LEFT JOIN으로 변환하는 방법

개념을 쉽게 이해하기 위해 아래 두 개의 샘플 테이블(customers, reserve)을 사용하겠습니다.

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 reserve;
+------+------------+
| ID   | Day        |
+------+------------+
| 1    | 2017-12-30 |
| 2    | 2017-12-28 |
| 2    | 2017-12-25 |
| 1    | 2017-12-24 |
| 3    | 2017-12-26 |
+------+------------+
5 rows in set (0.00 sec)

customers 테이블에는 고객 정보가, reserve 테이블에는 차량 예약 기록이 저장되어 있습니다.

1단계: 하위 쿼리 작성

먼저, 차량을 한 번도 예약하지 않은 고객의 이름을 찾는 하위 쿼리를 살펴보겠습니다.

mysql> Select Name from customers where customer_id NOT IN (Select id From reserve);
+----------+
| Name     |
+----------+
| Virender |
+----------+
1 row in set (0.00 sec)

이 쿼리는 NOT IN 연산자와 하위 쿼리를 사용하여 예약 이력이 없는 고객, 즉 Virender만 반환합니다.

2단계: 하위 쿼리를 LEFT JOIN으로 변환

다음 세 가지 단계를 거치면 위의 하위 쿼리를 LEFT JOIN으로 변환할 수 있습니다.

  • 하위 쿼리 안에 있던 'reserve' 테이블을 FROM 절로 옮기고, LEFT JOIN을 사용해 'customers' 테이블과 연결합니다.
  • 원래 WHERE 절은 customer_id 열과 하위 쿼리가 반환한 id 값을 비교했습니다. 따라서 IN 표현식을 FROM 절에 있는 두 테이블의 id 열 간 명시적인 직접 비교(ON 조건)로 바꿉니다.
  • 마지막으로 WHERE 절에서 'reserve' 테이블 쪽 값이 NULL인 행만 출력되도록 제한합니다.
mysql> SELECT Name from customers LEFT JOIN reserve ON customer_id = Id WHERE Id IS NULL;
+----------+
| Name     |
+----------+
| Virender |
+----------+
1 row in set (0.00 sec)

동작 원리

LEFT JOIN은 왼쪽 테이블(customers)의 모든 행을 유지하면서, 오른쪽 테이블(reserve)에 일치하는 행이 없으면 해당 열을 NULL로 채웁니다. 따라서 WHERE Id IS NULL 조건을 추가하면 예약 기록이 전혀 없는 고객, 즉 조인에 실패한 행만 정확히 걸러낼 수 있습니다.

참고로, 대용량 데이터에서는 옵티마이저가 조인을 더 효율적으로 처리하는 경우가 많기 때문에 NOT IN 하위 쿼리보다 LEFT JOIN + IS NULL 패턴이 성능 면에서 유리할 수 있습니다.