SQL - IN, NOT IN, EXISTS, NOT EXISTS 차이점 정리

송은·2024년 3월 17일
0

학생 테이블

학번이름학년
1111홍길동1
2222임꺽정2
3333유관순3
4444안중근3
5555홍범도4

IN

IN 구문에 입력된 값들 중에서 하나라도 일치하는 것이 있으면 조회된다.
즉, 쿼리가 실행될 때 내부적으로 or 연산자로 변경되어 실행되는 것이다.

IN 구문은 IN 연산자에 다른 SELECT문을 넣을 수 있다.(=서브쿼리)
대량의 값을 대입하거나, 동적으로 값이 변경되어야 할 때 IN 연산자에 서브쿼리를 사용할 수 있다.

SELECT * FROM 학생 WHERE 학년 IN (3, 4);
# or 연산자로 변환된 쿼리
SELECT * FROM 학생 WHERE (학년 = 3 OR 학년 = 4);

MySQL 5.6에서 서브쿼리가 대폭 개선되었으며, MySQL 5.5까지는 서브쿼리의 최적화 성능이 좋지 않아 JOIN으로 전환하여 실행되는 것이 좋다. MySQL 5.6는 서브쿼리 사용 시 내부적으로 JOIN으로 실행된다.

서브쿼리

Q. 학생 테이블에서 학년이 3인 학생들의 학번을 선택

SELECT * FROM 학생
WHERE 학번 IN (SELECT 학번 FROM 학생 WHERE 학년 = 3);

NOT IN

IN 구문의 경우 서브쿼리의 결과로 나온 값들 중 일치하는 값이 하나라도 있으면 되지만, NOT IN을 사용할 경우 서브쿼리의 결과로 나온 모든 값들과 일치하지 않는지를 체크하게 된다.

즉, IN 구문의 경우 내부적으로 or 연산자로 변경되었다면, NOT IN 구문의 경우 and 연산자로 변경된다.

Q. 학생 테이블에서 학년이 3이 아닌 학생들의 학번을 선택

SELECT * FROM 학생
WHERE 학번 NOT IN (SELECT 학번 FROM 학생 WHERE 학년 = 3);

EXISTS

EXISTS 구문에서는 IN 구문과는 다르게 메인 쿼리에 먼저 접근하여 값을 가져오고, EXISTS의 서브쿼리를 실행시켜 결과가 존재하는지를 판단한다.
IN 연산자는 비교할 값을 직접 대입할 수 있지만, EXISTS 연산자는 서브쿼리만 사용할 수 있다는 특징이 있다.

  • IN: 서브쿼리 → 메인쿼리 → 도출
  • EXISTS: 메인쿼리 → 서브쿼리 → 도출

서브쿼리의 결과가 true인지 false인지 체크하기 때문에 결과가 존재할 경우(=true) 메인 쿼리의 결과를 출력한다.

Q. "학년"이 특정 학년보다 높은 학생을 선택

SELECT * FROM 학생 s
WHERE EXISTS (SELECT 1 FROM 학생 WHERE 학년 > 2 AND 학번 = s.학번);
  • 서브쿼리에서 학생 테이블에서 학년이 2보다 큰 학생이 있는지 확인한다
  • 서브쿼리가 참이면 메인쿼리가 실행되고, 결과적으로 학년이 2보다 큰 학생들의 정보만 반환된다.

NOT EXISTS

NOT EXISTS에서는 서브쿼리 내의 결과가 존재하지 않을 경우(=false) 메인 쿼리의 결과를 출력한다.


서브쿼리 개념

1개의 SQL 문장 내에서 먼저 A라는 질문의 답을 구하고, 이 값을 B라는 질문의 조건으로 사용하여 최종적인 값을 도출해야 하는 경우가 있다. 이 때 사용하는 것이 서브쿼리이다.

예)

  • A보다 급여를 더 많이 받는 / 더 적게 받는 사람
    : A의 급여를 구하고(서브쿼리) → 이 값을 기준으로 더 많이/더 적게 받는 사람을 출력(메인쿼리)
  • B부서 평균보다 더 적은 급여를 받는 사람
    : B부서의 평균 급여를 구하고(서브쿼리) → 이 값보다 더 적은 급여를 받는 사람을 출력(메인쿼리)
  • 전 세계 평균보다 GDP가 더 높은 / 더 낮은 국가
    : 전 세계 평균 GDP를 구하고(서브쿼리) → 이 값보다 더 높거나 낮은 국가를 출력(메인쿼리)
SELECT 컬럼이름A, 컬럼이름B, ...
FROM 테이블이름
WHERE 조건연산자 (서브쿼리);
SELECT 컬럼이름A, 컬럼이름B, ...
FROM 테이블이름
WHERE 조건연산자 (SELECT X FROM 테이블이름 WHERE 조건);
  • 서브쿼리는 WHERE절 연산자의 오른쪽에 위치한다.
  • 반드시 괄호 안에 서술한다.
  • 서브쿼리절에는 ORDER BY 사용 불가
  • 서브쿼리를 포함한 메인쿼리 문장 전체에서 세미콜론(;)은 문장이 끝날 때 1번만 사용
  • 서브쿼리 내에는 세미콜론(;)을 넣지 않음
  • 서브쿼리 내부에서도 WHERE 뿐만 아니라 GROUP BY, HAVING 사용 가능

출처
서브쿼리의 개념
IN, NOT IN, EXISTS, NOT EXISTS 동작 방식 정리

profile
개발자

0개의 댓글