CodeGym /행동 /SQL SELF /데이터 존재 여부 확인하기: EXISTS 와 NOT EXISTS

데이터 존재 여부 확인하기: EXISTS 와 NOT EXISTS

SQL SELF
레벨 13, 레슨 3
사용 가능

SQL 새 강의에 온 걸 환영해! 오늘은 가장 눈에 잘 안 띄지만 진짜 강력한 연산자 — EXISTS 와 NOT EXISTS를 배워볼 거야. 마치 흔적도 안 남기고 "응, 객체 있어" 아니면 "아니, 여긴 비었어"라고 바로 알려주는 첩보원 같다고 생각해봐. 이 연산자들은 데이터를 직접 반환하진 않지만, 논리적으로 딱 맞는 체크를 쿼리에서 할 수 있게 해줘.

기본부터 시작하자. EXISTS는 레코드가 존재하는지 서브쿼리 결과로 확인하는 연산자야. 만약 서브쿼리가 한 줄이라도 반환하면 EXISTS는 TRUE를, 아니면 FALSE를 반환해.

SELECT 1
WHERE EXISTS (
    SELECT * 
    FROM students 
    WHERE grade > 3.5
);

보다시피, 서브쿼리의 데이터 자체엔 관심 없고, 그런 행이 존재하는지만 보는 거야. 조건에 맞는 레코드가 하나라도 있으면 쿼리는 1을 반환해.

EXISTS 문법

EXISTS 문법은 진짜 간단해:

SELECT 컬럼들
FROM 테이블
WHERE EXISTS (
    SELECT 1
    FROM 다른_테이블
    WHERE 조건
);

설명:

  • EXISTS 안의 서브쿼리는 아무 쿼리나 올 수 있어.
  • 서브쿼리 결과가 TRUE 또는 FALSE를 결정해.

예시: 4점 넘는 학생이 있나?

students 테이블을 상상해보자:

id name grade
1 Otto 3.2
2 Anna 4.7
3 Dan 5.0
4 Lina 2.9

이제 4점 넘는 학생이 있는지 확인하고 싶어. 아래 쿼리를 써보자:

SELECT '점수 높은 학생이 있어!'
WHERE EXISTS (
    SELECT 1
    FROM students
    WHERE grade > 4
);

결과:

점수 높은 학생이 있어!

왜 EXISTS가 IN보다 빠를까?

EXISTS의 가장 큰 장점은 서브쿼리에서 첫 번째로 조건에 맞는 행을 찾으면 바로 멈춘다는 것이야. 즉, 데이터가 있는지만 확인할 때 EXISTS는 엄청 효율적일 수 있어.

예를 들어, students 테이블에 수백만 개의 레코드가 있어도, 우리는 단 하나의 조건에 맞는 행(grade > 4)만 찾으면 돼. SQL이 첫 번째로 맞는 행을 찾는 순간 쿼리는 끝나.

NOT EXISTS 사용하기

이제 NOT EXISTS에 대해 얘기해보자. 이 연산자는 EXISTS의 반대야. 서브쿼리가 아무 행도 반환하지 않을 때 TRUE를 반환해.

예시: 점수가 없는 학생 찾기 (NULL)

우리 테이블에 아직 점수가 없는 학생이 있다고 해보자:

id name grade
1 Otto NULL
2 Anna 4.7
3 Dan 5.0
4 Lina NULL

점수가 없는 학생만 뽑고 싶으면 NOT EXISTS를 써봐:

SELECT *
FROM students s
WHERE NOT EXISTS (
    SELECT 1
    FROM students 
    WHERE grade IS NOT NULL
    AND id = s.id
);

결과:

id name grade
1 Otto NULL
4 Lina NULL

EXISTS vs IN 비교

가끔 EXISTS랑 IN이 똑같아 보일 때가 있어. 얼핏 보면 맞지만, NULL이 끼어들면 얘기가 달라져. 이럴 때 IN은 예측 못한 결과를 주기도 하고, EXISTS가 구세주가 돼.

예제로 보자.

courses 테이블 (수강 가능한 과목):

course_id name
1 수학
2 역사

그리고 학생들:

student_id name
1 Alex Lin
2 Anna Song
3 Maria Chi
4 Dan Seth
5 Shadow Moon

enrollments 테이블 (누가 어떤 과목에 등록했는지):

student_id course_id
1 1
2 2
3 NULL

누군가 등록한 과목 이름을 뽑고 싶어. 쉬워 보이지?

IN 사용:

SELECT name
FROM courses
WHERE course_id IN (
    SELECT course_id 
    FROM enrollments
);

겉보기엔 잘 될 것 같지만, enrollments에 NULL이 들어가 있으면(Maria Chi처럼) IN이... 아무것도 안 줄 수도 있어! 왜냐면 NULL이 서브쿼리를 "불확실"하게 만들어서, SQL이 "혹시 NULL이 우리가 찾는 그 course_id일 수도 있잖아?"라고 헷갈려 하거든.

EXISTS 사용:

SELECT name
FROM courses c
WHERE EXISTS (
SELECT 1
FROM enrollments e
WHERE c.course_id = e.course_id
);

EXISTS는 "course_id가 일치하는 행이 하나라도 있냐?"만 체크해. NULL이 있어도 신경 안 써, 그냥 일치하는 값만 찾으니까.

결론: 서브쿼리에 NULL이 있을 수 있으면 EXISTS를 쓰는 게 안전해. 그래야 이상한 결과 안 나와.

실제 문제 예시

students 테이블:

id name
1 Alex Lin
2 Anna Song
3 Maria Chi
4 Dan Seth
5 Shadow Moon

enrollments 테이블:

student_id course_id
1 1
2 2
3 NULL

예시 1. 과목에 등록한 학생들

이미 어딘가 등록한 학생을 찾아보자 (Maria Chi처럼 이상하게 등록했어도):

SELECT name
FROM students s
WHERE EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE s.id = e.student_id
);

결과:

Alex Lin
Anna Song
Maria Chi

학생이 enrollments에 한 번이라도 나오면, course_id가 뭔지 상관없이 결과에 들어가.

예시 2. 아직 과목에 등록 안 한 학생들

이제 시스템에만 있고 아직 아무데도 등록 안 한 학생을 찾아보자:

SELECT name
FROM students s
WHERE NOT EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE s.id = e.student_id
);

결과:

Dan Seth
Shadow Moon

이 둘은 아직 마음에 드는 과목을 못 찾았나 봐. 아니면 그냥 등록하는 걸 까먹었을 수도 있지 :)

예시 3. 5명 넘게 등록한 과목 찾기

courses 테이블:

course_id name
1 수학
2 역사
3 생물학
4 철학

enrollments 테이블:

student_id course_id
1 1
2 1
3 1
4 1
5 1
6 1
7 2
8 2
9 2
10 NULL

5명 넘게 등록한 과목을 찾고 싶어. 여기서 EXISTS는 "이 과목에 학생이 5명 넘게 등록한 그룹이 있냐?"고 묻는 거야.

SELECT name
FROM courses c
WHERE EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE c.course_id = e.course_id
    GROUP BY e.course_id
    HAVING COUNT(*) > 5
);

결과:

수학

"수학"(course_id = 1)만 6명이 등록했어. 다른 과목은 아직 인기 별로야.

EXISTS 와 NOT EXISTS 쓸 때 자주 하는 실수

  1. 서브쿼리 문법을 잘못 이해함. 항상 서브쿼리가 외부 테이블을 제대로 참조하는지 확인해.
  2. NULL 체크를 빼먹음. EXISTS를 써도 가끔 NULL 처리를 명확히 해줘야 할 때가 있어.
  3. 서브쿼리 필드에 인덱스가 없음. 이러면 쿼리가 엄청 느려질 수 있어.

오늘은 여기까지! 이제 EXISTS 와 NOT EXISTS로 데이터 존재 여부를 체크하는 법, 그리고 이 연산자들과 IN의 차이까지 알게 됐지. 다음 강의에선 SELECT에서 서브쿼리로 집계 데이터 다루는 법을 더 파볼 거야.

2
과제
SQL SELF, 레벨 13, 레슨 3
잠금
성적이 없는 학생 찾기
성적이 없는 학생 찾기
2
과제
SQL SELF, 레벨 13, 레슨 3
잠금
등록된 학생이 있는 강좌 확인하기
등록된 학생이 있는 강좌 확인하기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION