IN, NOT IN, EXISTS, NOT EXISTS는 서브쿼리와 함께 사용되어 특정 조건에 맞는 데이터를 필터링하는 데 사용됩니다. SQLD 시험에서는 각 연산자의 동작 방식, 특히 NULL 값 처리에서의 차이점을 정확히 구분하는 문제가 자주 출제됩니다.
WHERE user_id IN (1, 2, 3)은 WHERE user_id = 1 OR user_id = 2 OR user_id = 3과 동일합니다.NOT IN을 사용하는 서브쿼리 결과에 NULL 값이 하나라도 포함되어 있으면, NOT IN 조건은 결과적으로 UNKNOWN이 되어 어떤 행도 반환하지 않습니다.SELECT 1을 사용하는 것이 일반적입니다.TRUE를 반환합니다.EXISTS는 서브쿼리의 조건을 만족하는 첫 번째 행이 발견되면 바로 처리를 중단하므로, 대용량 데이터 처리 시 IN보다 성능이 더 좋을 수 있습니다.| 구분 | IN / NOT IN | EXISTS / NOT EXISTS |
|---|---|---|
| 동작 방식 | 값 비교 (서브쿼리 결과와 메인쿼리 컬럼 값) | 존재 여부 확인 (서브쿼리에 행이 있는지) |
| NULL 처리 | NOT IN에서 NULL이 있으면 오류 | NULL에 영향을 받지 않음 |
| 주요 사용처 | 고정된 값의 리스트 또는 소규모 서브쿼리 | 상관 서브쿼리, 대규모 서브쿼리 |
NOT IN 서브쿼리에 **NULL이 포함된 경우 결과는 UNKNOWN**이 되어 아무것도 반환하지 않는다는 점을 반드시 기억해야 합니다.EXISTS는 서브쿼리의 반환 컬럼은 중요하지 않습니다. SELECT * 대신 SELECT 1을 사용하는 것이 일반적입니다.EXISTS와 NOT EXISTS는 특정 조건에 부합하는 JOIN을 대체할 수 있으며, 성능상 더 효율적일 때가 많습니다.IN**은 값 비교, **EXISTS**는 존재 여부!NOT IN**은 **NULL**이라는 함정에 빠지면 결과가 없다!NOT EXISTS**는 **NULL**에 영향을 받지 않는다!1. 다음 쿼리 결과로 반환되는 행의 개수는?
(Users 테이블의 user_id = {1, 2, 3, 4})
SELECT * FROM Users WHERE user_id NOT IN (1, 2, NULL);
A. 0개
B. 1개
C. 2개
D. 3개
2. 아래 SQL의 의미로 가장 올바른 것은?
SELECT * FROM Users U
WHERE EXISTS (SELECT 1 FROM Orders O WHERE U.user_id = O.user_id);
A. 주문이 존재하지 않는 유저를 출력한다.
B. 주문이 하나라도 있는 유저만 출력한다.
C. 주문이 여러 개인 유저만 출력한다.
D. Orders 테이블 전체를 반환한다.
3. 다음 중 EXISTS와 IN에 대한 설명으로 틀린 것은?
A. EXISTS는 NULL에 영향을 받지 않는다.
B. IN은 = 조건을 OR로 연결한 것과 유사하다.
C. NOT EXISTS는 서브쿼리 결과가 없는 경우 TRUE를 반환한다.
D. NOT IN은 서브쿼리 결과에 NULL이 포함되어 있으면 TRUE를 반환한다.
NOT IN의 리스트에 NULL이 포함되어 있으므로, 결과는 UNKNOWN이 되어 어떤 행도 반환하지 않습니다.EXISTS는 서브쿼리(Orders 테이블)에 메인쿼리(Users 테이블)의 user_id와 일치하는 행이 하나라도 있는지 확인하므로, 주문 내역이 있는 모든 유저를 반환합니다.NOT IN은 서브쿼리 결과에 NULL이 포함되면 UNKNOWN을 반환하여 어떠한 행도 반환하지 않습니다. TRUE를 반환하지 않습니다.