글 목록

최신 글과 검색 결과
DEVELOPMENT

SQL, EXIST, NOT EXIST 알아보기

간지뽕빨리턴님

이 글의 목차

    반응형

    SQL EXISTS와 NOT EXISTS의 개념과 사용법, IN·JOIN과의 차이를 정리합니다.

    EXISTS와 NOT EXISTS, 쉽고 정확하게 정리

    SQL을 사용하다 보면 "어떤 조건을 만족하는 데이터가 다른 테이블에 존재하는가/존재하지 않는가"를 기준으로 결과를 걸러야 할 때가 많습니다. 이럴 때 쓰는 것이 EXISTSNOT EXISTS입니다.

     

    저도 아직 배우는 입장이지만, 개념과 사용법, 그리고 자주 비교되는 IN·JOIN과의 차이까지 예제와 함께 정리해 보겠습니다.

    목차

      EXISTS란

      EXISTS는 서브쿼리(Sub Query)의 결과가 한 건이라도 존재하면 참(TRUE)으로 판단하는 연산자입니다. 쉽게 말해 "메인 테이블의 각 행에 대해, 서브쿼리 조건을 만족하는 데이터가 존재하면 그 행을 보여줘!"라는 의미입니다. 실제 값을 가져오는 것이 아니라 '존재 여부'만 확인하기 때문에, 조건을 만족하는 행이 발견되는 즉시 검사를 멈춰 효율적입니다.

      기본 문법

      SELECT 조회할_컬럼
      FROM 메인테이블 m
      WHERE EXISTS (
          SELECT 1
          FROM 서브테이블 s
          WHERE s.key = m.key   -- 메인과 서브를 연결하는 상관 조건
      );

      서브쿼리에 SELECT 1이라고 쓴 것이 보이실 텐데, EXISTS는 '존재 여부'만 보기 때문에 어떤 컬럼을 가져오는지는 중요하지 않습니다. 그래서 관례적으로 의미 없는 1을 넣습니다(SELECT *를 써도 동작은 같습니다). 또한 WHERE s.key = m.key처럼 메인 테이블과 연결되는 조건이 들어가는데, 이렇게 바깥 쿼리의 값을 참조하는 서브쿼리를 상관 서브쿼리(Correlated Subquery)라고 합니다.

       

      NOT EXISTS란

      NOT EXISTS는 EXISTS의 반대입니다. "서브쿼리 조건을 만족하는 데이터가 존재하지 않을 때 그 행을 보여줘!"라는 의미입니다. 주로 "주문하지 않은 고객", "한 번도 시험에 응시하지 않은 학생"처럼 '~하지 않은' 대상을 찾을 때 사용합니다.

      SELECT 조회할_컬럼
      FROM 메인테이블 m
      WHERE NOT EXISTS (
          SELECT 1
          FROM 서브테이블 s
          WHERE s.key = m.key
      );

       

      예제로 보기

      고객(customers)과 주문(orders) 테이블이 있다고 가정하겠습니다.

      -- customers: 1 김철수, 2 이영희, 3 박민수
      -- orders   : 고객1, 고객1, 고객2   (3번 고객은 주문 없음)
      
      -- 주문한 적이 있는 고객 (EXISTS)
      SELECT c.name
      FROM customers c
      WHERE EXISTS (
          SELECT 1 FROM orders o WHERE o.customer_id = c.id
      );
      -- 결과: 김철수, 이영희
      
      -- 주문한 적이 없는 고객 (NOT EXISTS)
      SELECT c.name
      FROM customers c
      WHERE NOT EXISTS (
          SELECT 1 FROM orders o WHERE o.customer_id = c.id
      );
      -- 결과: 박민수

       

      EXISTS vs IN vs JOIN

      사실 위와 같은 결과는 IN이나 JOIN으로도 얻을 수 있습니다. 그렇다면 언제 무엇을 써야 할까요? 세 가지를 비교하면 다음과 같습니다.

      구분 특징 적합한 상황
      EXISTS 존재만 확인하고 즉시 중단 서브쿼리 결과가 크거나 '존재 여부'만 필요할 때
      IN 값 목록 전체와 비교 비교 대상 목록이 작고 단순할 때
      JOIN 두 테이블을 결합 양쪽 테이블의 컬럼이 함께 필요할 때

      일반적으로 서브쿼리 결과 집합이 클 때는 EXISTS가 IN보다 유리합니다. EXISTS는 일치하는 행을 하나 찾으면 바로 멈추기 때문입니다. 반대로 비교할 값 목록이 작고 고정적이면 IN이 직관적입니다. 두 테이블의 컬럼을 함께 조회해야 한다면 JOIN을 쓰는 것이 맞지만, JOIN은 조인 조건에 따라 중복 행이 생길 수 있어 '존재 여부'만 판단할 때는 EXISTS가 더 깔끔합니다.

       

      다만 어느 것이 빠른지는 DBMS의 옵티마이저와 인덱스 상황에 따라 달라지므로, 중요한 쿼리라면 실행 계획(EXPLAIN)으로 직접 확인하는 것이 가장 정확합니다.

       

      마무리

      EXISTS와 NOT EXISTS를 예제와 함께 정리했습니다. 핵심은 '값을 가져오는 것이 아니라 존재 여부를 판단한다'는 점, 그리고 '~한 적 있는/없는' 대상을 찾을 때 특히 유용하다는 점입니다.

       

      설명이 부족하거나 수정할 점이 있으면 댓글로 알려 주세요. 반영해 업데이트하겠습니다!