[MySQL] 서브쿼리

YTT.erica·2024년 6월 2일

서브쿼리

서브쿼리란 다른 쿼리 내부에 포함되어 있는 SELECT 문을 의미

  • 외부쿼리: 서브쿼리를 포함하고 있는 쿼리
  • 내부쿼리: 서브쿼리

예제) 주소가 서울인 고객이 예약한 예약 정보만을 선택

SELECT ID, ReserveDate, RoomNum
FROM Reservation
WHERE Name IN **(SELECT Name
	FROM Customer
	WHERE Address = '서울'
)

서브쿼리 특징

SELECT FROM WHERE HAVING ORDER BY INSERT 문의 VALUES UPDATE 문의 SET 에서 사용 가능

비교 연산자와 함께 사용 → < > = IN NOT IN EXIST NOT EXIST

괄호를 감싸서 사용

서브쿼리 내 ORDER BY 사용 불가


서브쿼리 사용 (in WHERE절)

단일 행 서브쿼리

서브쿼리가 단일 행 비교 연산자와 함께 사용할 때

SELECT name, age
FROM users
WHERE name = (SELECT name
							FROM posts
						  WHERE post_id = 1);

⚠️ 서브쿼리의 결과는 무조건 1개 이하여야 함

  • 단일 행 비교 연산자

    연산자의미
    >
    <작음
    크거나 같음
    작거나 같음
    =같음
    ! = , <>, ^=같지 않음

다중 행 서브쿼리

서브쿼리가 다중 행 비교 연산자와 함께 사용할 때

SELECT name, age
FROM users
WHERE name IN (SELECT name
	             FROM posts
	             WHERE post_id > 2);

⚠️ 서브쿼리의 결과가 2개 이상일 때 사용

  • 다중 행 비교 연산자
    연산자사용법의미
    IN(M) IN (S)서브쿼리의 결과 중에 하나라도 만족하는 것
    ANY, SOME(M) = ANY/SOME (S)서브쿼리의 결과 중에 하나라도 만족하는 것
    ANY, SOME(M) < ANY/SOME (S)서브쿼리의 결과 중 최댓값 보다 작은 것
    ANY, SOME(M) > ANY/SOME (S)서브쿼리의 결과 중 최솟값 보다 큰 것
    ALL(M) < ALL (S)서브쿼리의 결과 중 최솟값 보다 작은 것
    ALL(M) > ALL (S)서브쿼리의 결과 중 최댓값 보다 큰 것
    EXISTS(M) EXISTS (S)서브쿼리의 결과 중에 하나라도 만족하는 것
  • IN과 EXISTS 차이 IN, EXISTS 차이

다중 컬럼 서브쿼리

서브쿼리 결과가 다중 칼럼이고 메인쿼리의 조건과 동시에 비교할 때

SELECT name, image, age
FROM users
WHERE (name, image) IN (SELECT name, image
                   FROM posts
                   WHERE post_id = 3);

⚠️ name과 image는 users와 posts에 모두 존재하는 컬럼

연관 서브쿼리

서브쿼리 내에 메인쿼리 컬럼 사용

SELECT users.user_id, users.name, users.image
FROM users as users
WHERE (users.user_id, users.name) IN (SELECT posts.user_id, posts.name
                         FROM posts as posts
                         WHERE posts.name = users.name);

서브쿼리 사용 (in SELECT절)

서브쿼리가 한 행, 한 컬럼만을 반환할 때 사용

SELECT users.age, (SELECT AVG(enrolls.age) FROM enrolls as enrolls)
FROM users as users;

users 테이블

idnameage
1Alice25
2Bob30
3Charlie22

enrolls 테이블

iduser_idage
1125
2230
3322
4427

결과

ageAVG(enrolls.age)
2526
3026
2226

서브쿼리 사용 (in FROM절)

동적으로 조인 방식을 사용하는 것과 같음

SELECT users.id, enrolls.user_id, enrolls.course_id
FROM users,
     (SELECT user_id, course_id FROM enrolls) enrolls
WHERE users.id = enrolls.user_id;

users 테이블

idnameage
1Alice25
2Bob30
3Charlie22

enrolls 테이블

iduser_idcourse_id
11101
22102
33103
41104

결과

iduser_idcourse_id
11101
11104
22102
33103

서브쿼리 장단점

서브쿼리 : 생존기간(스코프)이 SQL 구문 실행 중으로 한정

장점

기능적으로 유연

조인과 관련된 쿼리에서 서브쿼리가 더 나은 경우가 존재

→ 테이블을 조인할 때 조인 대상 레코드 수를 최대한 줄이는 것이 중요하나 옵티마이저가 제대로 판단하지 못할 때 사용자가 서브쿼리로 직접 연산 순서를 명시해줌으로써 성능적으로 좋을 수 있음

단점

테이블에 비해 성능이 떨어짐 → 서브 쿼리가 데이터의 실체를 저장하지 않고 있기 때문

  • 연산 비용: 매번 SELECT 문이 실행되기 때문에 내용이 복잡할 수록 비용이 큼
  • 데이터 I/O 비용: 서브 쿼리의 결과 데이터 양이 크면 연산 결과를 저장소에 씀
  • 최적화 불가능: 서브 쿼리의 결과 집합에는 인덱스나 제약조건이 없음

→ 내부적으로 복잡한 연산을 수행하거나 결과 크기가 큰 서브 쿼리를 사용할 때는 성능 리스크를 고려해야함


참고자료

[DATABASE] 서브쿼리란? 서브쿼리 사용해보기

코딩강아지 : 네이버 블로그

profile
'◡'✿ 꿈을 찾아가보자고~ '◡'✿

0개의 댓글