서브쿼리(Subquery) 란?

서브쿼리(Subquery)란 하나의 SQL 쿼리 내에서 사용되는 다른 SQL 쿼리를 의미한다. 예를 들어 조직(1) 과 사원(M) 테이블을 조인하면 결과는 사원 레벨(M) 의 집합이 생성된다. 그러나 서브쿼리는 서브쿼리 레벨과는 상관없이 항상 메인쿼리 레벨로 결과 집합이 생성된다. 메인쿼리로 조직(1), 서브쿼리로 사원 테이블(M)을 사용하면 결과 집합은 조직(1) 레벨이 된다.

SQL문에서 서브쿼리 방식을 사용해야 할 때 잘못 판단하여 조인 방식을 사용하는 경우가 있다. 예를 들어 결과는 조직 레벨이고 사원 테이블에서 체크해야 할 조건이 존재한다고 가정하자. 이런 상황에서 SQL문을 작성할 때 조인을 사용한다면 결과 집합은 사원 레벨(M)이 될 것이다. 이렇게 되면 원하는 결과가 아니기 때문에 SQL문에 DISTINCT를 추가해서 결과를 다시 조직(1) 레벨로 만든다. 이와 같은 상황에서는 조인 방식이 아니라 서브쿼리 방식을 사용해야 한다. 메인쿼리로 조직을 사용하고 서브쿼리로 사원 테이블을 사용하면 결과 집합은 조직 레벨이 되기 때문에 원하는 결과가 된다.

동작하는 방식에 따른 서브쿼리 분류

1. Un-Correlated(비연관) 서브쿼리

  • Un-Correlated 서브쿼리는 메인 쿼리와 독립적으로 실행되는 서브쿼리
  • 서브쿼리가 메인쿼리 컬럼을 가지고 있지 않은 형태의 서브쿼리
  • 메인 쿼리는 이 서브쿼리의 결과를 사용하여 자신의 연산을 수행한다.
  • 메인쿼리에 값(서브쿼리가 실행된 결과)을 제공하기 위한 목적으로 주로 사용한다.

SELECT 이름, 부서ID
FROM 직원
WHERE 급여 > (
    SELECT AVG(급여)
    FROM 직원
);

 

 

 

2. Correlated(연관) 서브쿼리

  • Correlated 서브쿼리는 메인 쿼리의 각 행과 직접적인 관련이 있는 서브쿼리
  • 서브쿼리가 메인쿼리 컬럼을 가지고 있는 형태의 서브쿼리
  • 일반적으로 메인쿼리가 먼저 수행되어 읽혀진 데이터를 서브쿼리에서 조건이 맞는지 확인하고자 할 때 주로 사용된다.
  • 즉, 메인 쿼리의 각 행마다 서브쿼리가 다시 계산되어 결과를 도출합니다.
SELECT 이름, 부서ID
FROM 직원 e
WHERE 급여 = (
    SELECT MAX(급여)
    FROM 직원
    WHERE 부서ID = e.부서ID
);

 

 

 

반환되는 데이터의 형태에 따른 서브쿼리 분류

1. Single Row(단일 행) 서브쿼리

  • 단일 행 서브쿼리는 단 하나의 행만을 반환하는 서브쿼리
  • 이 서브쿼리는 주로 단일 행 비교 연산자(=, >, <, <=, >=, <>)와 함께 사용
  • 단일 행 서브쿼리는 결과가 반드시 하나의 행과 하나의 컬럼을 반환
SELECT 이름, 부서ID
FROM 직원
WHERE 급여 = (
    SELECT MAX(급여)
    FROM 직원
    WHERE 부서ID = '개발'
);
SELECT PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버
FROM PLAYER
WHERE TEAM_ID = (SELECT TEAM_ID
		FROM PLAYER
		WHERE PLAYER_NAME = '정남일') 
ORDER BY PLAYER_NAME;

 

2. Multi Row(다중 행) 서브쿼리

  • 다중 행 서브쿼리는 하나 이상의 행을 반환할 수 있는 서브쿼리
  • 이 유형의 서브쿼리는 IN, ANY, ALL, EXISTS와 같은 다중 행 비교 연산자와 함께 사용
SELECT 이름, 부서ID
FROM 직원
WHERE 부서ID IN (
    SELECT 부서ID
    FROM 부서
    WHERE 위치 = '서울'
);
SELECT PLAYER_NAME , POSITION , BACK_NO 예제 선수명 포지션 백넘버
FROM PLAYER
WHERE HEIGHT <= (SELECT AVG(HEIGHT)
		FROM PLAYER)
ORDER BY PLAYER_NAME;

 

 

3. Multi Column(다중 컬럼) 서브쿼리

  • 다중칼럼 서브쿼리는 하나 이상의 컬럼을 반환하는 서브쿼리
  • 메인 쿼리와의 비교에 여러 컬럼을 동시에 사용
  • 이러한 서브쿼리는 특히 조인을 대체할 때 유용하게 사용
SELECT 이름, 급여
FROM 직원
WHERE (부서ID, 급여) IN (
    SELECT 부서ID, MAX(급여)
    FROM 직원
    GROUP BY 부서ID
);
SELECT REGION_NAME 연고지명, TEAM_NAME 팀명, E_TEAM_NAME 영문팀명
FROM TEAM
WHERE TEAM_ID IN (SELECT TEAM_ID
		FROM PLAYER
		WHERE PLAYER_NAME = '정현수') 
ORDER BY TEAM_NAME;

 

 

 

그 외 서브쿼리

1. 스칼라 서브쿼리

  • 정확히 하나의 행과 하나의 컬럼을 반환하는 서브쿼리
  • SELECT 문의 SELECT 리스트 내부 또는 WHERE 조건에서 단일 값을 제공하는데 사용
  • 스칼라 서브쿼리는 하나의 값을 반환하므로 메인 쿼리의 각 행마다 연산을 수행

2. 인라인 뷰 (Inline View)

  • SELECT 문 내에서 FROM 절에 정의되는 서브쿼리
  • 일시적인 테이블처럼 사용
  • 복잡한 쿼리를 단순화하거나 재사용을 피할 수 있으며, 계산된 테이블을 바탕으로 추가적인 선택, 조인, 필터링을 수행

3. Top-N 서브쿼리

  • 특정 기준에 따라 상위 N개의 결과만을 반환하는 서브쿼리
  • 일반적으로 정렬(ORDER BY)와 함께 행 제한(LIMIT, FETCH FIRST, ROWNUM)을 사용하여 구현
SELECT 이름, 급여
FROM (
    SELECT 이름, 급여
    FROM 직원
    ORDER BY 급여 DESC
    FETCH FIRST 10 ROWS ONLY
) AS TopSalaries;

 

'DataBase > SQLD' 카테고리의 다른 글

윈도우 함수(WINDOW 함수)  (2) 2024.04.26
그룹함수(Group Function)  (0) 2024.04.26
계층형 질의(Hierarchical Query) - Oracle  (0) 2024.04.26
분산 데이터베이스의 투명성  (0) 2024.04.23
정규화(Normalization)  (0) 2024.04.23

+ Recent posts