본문 바로가기
데이터 모델과 SQL

[SQL 이해하기] - 9. SQL: 서브쿼리

by 영바이트 2023. 7. 4.

 

관심의 대상이 되는 집합을 먼저 구하고 다시 추가적인 조건을 적용하여 이들 집합 안에서 데이터를 추려내는 작업 순서가 꽤 자주 쓰인다. 이와 같은 작업 순서에서 '관심의 대상이 되는 집합을 먼저 구하는' 작업을 쿼리 안의 쿼리로 수행할 수 있고 이와 같은 쿼리를 서브쿼리(subquery)라고 한다. 예를 통해 살펴보자.

SELECT STUD_ID, STUD_FIRST_NAME, STUD_LAST_NAME
FROM	(SELECT * 
	FROM STUDENTS
	WHERE STUD_ID BETWEEN 2300000 AND 2399999)
WHERE STUD_MAJOR='사회복지학';

 

위 SQL은 학번이 23학번인 학생들로 이루어진 집합을 먼저 구하고 이 집합 안에서 전공이 '사회복지학'인 학생들의 정보를 얻는 쿼리이다. 여기서 학번이 23학번인 학생들로 이루어진 집합을 구하는 아래 쿼리가 서브쿼리다.

SELECT * FROM STUDENTS WHERE STUD_ID BETWEEN 2300000 AND 2399999

 


 

서브쿼리의 위치에 따라 서브쿼리는 다시 세 종류로 나뉜다.

위치 서브쿼리 종류 서브쿼리가 반환하는 데이터
SELECT절 안 스칼라(Scalar) 서브쿼리 하나의 값
FROM절 안  인라인 뷰(Inline view) 하나 이상의 컬럼으로 이루어진 하나 이상의 행
WHERE절 안 또는 HAVING 절 안 중첩(Nested) 서브쿼리 하나 이상의 컬럼으로 이루어진 하나 이상의 행

 

각각의 예를 살펴보자.

 

- 스칼라 서브쿼리

SELECT ORDER_ID, 
	(SELECT 
	PRODUCT_NAME 
	FROM PRODUCTS 
	WHERE PRODUCTS.PRODUCT_ID=ORDERS.PRODUCT_ID) 
FROM ORDERS 
WHERE ORDER_DATE=TO_DATE('20221211');

주문일이 2022년 12월 11일인 주문들을 출력하면서 '상품 테이블(PRODUCTS)에서 주문 상품 번호와 같은 상품의 이름을 함께 출력'한다.

 

- 인라인 뷰

SELECT ORDER_ID, PRODUCT_ID 
FROM (SELECT * 
	FROM ORDERS 
	WHERE PRODUCT_ID IN ('D301', 'D206', 'B002') 
WHERE ORDER_DATE=TO_DATE('20221211');

'제품 ID(PRODUCT_ID)가 'D301', 'D206', 'B002'인 제품들을 주문 테이블(ORDERS)에서 먼저 구한 후' 이들 중 주문일(ORDER_DATE)이 2022년 12월 11일인 제품의 주문 번호와 제품 번호를 출력한다.

 

- 중첩 서브쿼리

SELECT CUSTOMER_ID, PRODUCT_ID 
FROM ORDERS 
WHERE ORDER_ID IN (SELECT ORDER_ID FROM ORDERS WHERE ORDER_DATE=TO_DATE('20221211'));

예를 위해 다소 비효율적인 쿼리를 생성하였다. 쿼리 내용은 2022년 12월 11일에 주문된 주문들의 모든 주문 ID를 구한 후 이들 주문들의 주문자 번호(CUSTOMER_ID)와 제품 번호(PRODUCT_ID)를 출력하였다.

 

서브쿼리를 포함하는 바깥쪽 쿼리를 메인쿼리(main query)라 부른다. 서브쿼리와 메인쿼리는 서로 관련이 있을 수도 있고 서로 독립적일 수도 있다. 서브쿼리와 메인쿼리가 서로 관련이 있는 경우, 예를 들어 위에서 살펴본 스칼라 서브쿼리에서와 같이 메인 쿼리의 정보를 가져와 서브쿼리에서 사용하는 경우 연관 서브쿼리(Correlated subquery)라 부른다. 그리고 위의 인라인 뷰, 중첩 서브쿼리의 예와 같이 서브 쿼리가 독립적인 경우 비연관 서브쿼리(Uncorrelated subqeury)라 부른다.

 

 

 

댓글