본문 바로가기
데이터베이스

[SQLD] 서브 쿼리(Sub Query) 개념 및 종류

by 데이널 2023. 12. 4.

이번 포스팅에서는 서브 쿼리에 대해 알아보도록 하겠습니다. 서브 쿼리는 SQL을 작성할 때 여러 가지 복잡한 문제를 해결해 주는 방법 중에 하나입니다. 서브쿼리만 잘 작성해도 'SQL 잘 짠다'는 말을 들을 수 있죠. 이번 글에서 서브 쿼리의 개념을 이해하고 어떤 종류들이 있는지에 대해 살펴보도록 하겠습니다. 
 

 

서브 쿼리(Sub Query)란

서브 쿼리라는 말부터 이해 해보면, Sub라는 말은 어디에 종속된 쿼리라는 것이죠. 그래서 서브 쿼리는 SQL문 안에 포함된 형태로 존재합니다. 한마디로 말해 서브 쿼리는 데이터 연결방식의 일종인 거죠.

아래 그림처럼 메인 되는 쿼리를 주(Main) 쿼리 안에 존재하게 됩니다. 괄호 안에 정의된 쿼리를 부(Sub) 쿼리라고 합니다. 주(main) 쿼리에 종속된 부(sub) 쿼리로써 종속성을 갖는 쿼리라고 할 수 있습니다.
 
그렇다면 이 Sub Query를 사용하는 이유는 뭘까요?

1. 복잡한 연산 간소화

서브쿼리를 사용하여 복잡한 계산이나 연산을 괄호로 묶어서 수행할 수 있습니다. 서브쿼리를 사용하여 계산된 값을 기반으로 메인 쿼리에서 추가적인 연산이 가능하기 때문에 훨씬 이해하기 쉽습니다.

2. 데이터 필터링

쿼리에서 조건 절에서 상수 값이나 원래의 값으로 비교할 수 없을 때 사용할 수 있습니다. 서브 쿼리(Sub-Query)를 사용하여 괄호 안에 방식으로 어떠한 가공을 한 값으로 비교하고자 할 때에 사용하죠. 서브 쿼리는 주 쿼리의 속성을 그대로 이어받지만 주 쿼리에서는 서브 쿼리의 내용을 참조할 수 없습니다. 반대로 서브 쿼리에서 주 쿼리의 내용을 참조할 수는 있습니다.
 

Sub Query
Sub Query

 

3. 유연성과 재사용성

WITH절을 사용하는 것도 서브쿼리의 하나의 기법입니다. 서브쿼리를 사용하여 쿼리를 더 유연하게 만들고 재사용할 수 있습니다. 서브쿼리를 사용하면 쿼리를 더 작은 단위로 분할하여 로직을 이해하기 쉽고 유지보수가 용이한 코드를 작성할 수 있습니다.
 

Sub Query 종류

서브 쿼리는 사용 위치에 따라 3가지 명칭으로 구분하여 사용합니다. 스칼라 서브 쿼리의 경우 배치 작업과 같은 데이터를 많이 다루는 SQL에서는 주위해야 합니다. 데이터 이행 프로젝트에서 개발자가 스칼라 서브 쿼리를 남발해 속도가 느려진 경험이 있습니다. 

 

1. 스칼라 서브 쿼리 - SELECT 절에 사용

  • 단일 컬럼, 단일 행을 반환(1개의 값)
  • 결과 집합이 적을 때 사용, 많을 경우 성능이슈 발생

2. 인라인 뷰 - FROM 절에 사용

  • View와 사용적인 측면에서 동일함
  • View는 데이터베이스에 정의되어 사용되지만 서브 쿼리는 쿼리 실행 시 정의됨

3. 중첩 서브 쿼리 - WHERE 절, HAVING 절에 사용

  • 다중 컬럼 또는 다중 행을 반환
  • 단, = 비교 일 때는 단일 행 반환

서브 쿼리 종류
서브 쿼리 종류

 
동작 방식은에 따른 분류로는 비연관 서브쿼리와 연관 서브쿼리로 나눌 수 있습니다.  
비연관은 메인쿼리와 서브 쿼리가 컬럼을 공유하지 않는 것을 말하고, 연관 서브 쿼리는 아래 SQL문처럼 메인 쿼리의 PLAYER의 TEAM_ID와 서브 쿼리의 TEAM_ID를 조인 걸어 서로 연관되는 쿼리를 말합니다. 
 

 

1
2
3
4
5
6
7
8
9
10
11
12
SELECT T.TEAM_NAME 팀명, M.PLAYVER_NAME 선수명
FROM PLAYER M, TEAM T 
WHERE M.TEAM_ID = T.TEAM_ID 
AND M.HEIGHT < (SELECT AVG(S.HEIGHT) 
                FROM PLAYER S 
                WHERE S.TEAM_ID = M.TEAM_ID 
                AND    S.HEIGHT IS NOT NULL
                GROUP BY S.TEAM_ID 
                ) 
ORDER BY 선수명
 
cs

 

 분류 영문명 한글명 설명
동작방식에 따른 분류 Un-Correlated Subquery 비연관 서브쿼리 서브쿼리가 메인쿼리 컬럼을 가지고 있지 않은 형태. 메인쿼리에 값을 제공하기 위한 목적으로 주로 사용된다.
Correlated Subquery 연관 서브쿼리 서브쿼리가 메인쿼리 컬럼을 가지고 있는 형태. 일반적으로 메인쿼리가 먼저 수행되어 읽혀진 데이터를 서브쿼리에서 조건이 맞는지 확인하고자 할 때 주로 사용된다.
메인쿼리의 값을 서브쿼리에서 주입을 받아서 비교를 하는것으로 상호연관 서브쿼리

 
변환되는 데이터 형태에 따른 분류는 단일행, 다중행, 다중 컬럼 서브 쿼리 세 가지로 분류됩니다. 
단일행과 다중행은 서브 쿼리의 실행결과가 1건이냐, 아니면 그 이상이냐로 구분됩니다. 그리고 다중 컬럼 서브 쿼리는 아래 SQL문과 같이 컬럼을 두 개(TEAM_ID, HEIGHT)를 동시에 비교하는 것을 말합니다. 실제로 다중 서브쿼리는 여러행의 조건을 리턴 받을 때 매우 유용합니다. 
 

1
2
3
4
5
6
7
8
SELECT TEAM_ID 팀코드, PLAYVER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE (TEAM_ID, HEIGHT) IN (SELECT TEAM_ID, MIN(HEIGHT) 
                            FROM PLAYER 
                            GROUP BY TEAM_ID) 
ORDER BY TEAM_ID, PLAYER_NAME 
 
cs

 

 분류 영문명 한글명 설명
반환되는 데이터 형태에 따른 분류 Single Row Subquery 단일행 서브쿼리 서브쿼리 실행 결과가 항상 1건 이하. 딘일행 서브쿼리는 단일 행 비교 연산자( =, <. > <=, >=, <>) 와 함께 사용된다.
Multi Row Subquery 다중행 서브쿼리 서브쿼리 실행 결과가 여러 건 발생하는 IN, ALL, ANY, SOME, EXISTS 와 함께 사용된다.
Multi Column Subquery 다중 컬럼 서브쿼리 서브쿼리의 실행 결과로 여러 컬럼을 반환한다. 메인쿼리의 조건절에 여러 컬럼을 동시에 비교할 수 있다. 서브쿼리와 메인쿼리에서 비교하고자 하는 컬럼 개수와 컬럼의 위치가 동일해야 한다.

 

마무리

서브 쿼리는 단일 값, 다중 행, 전체 테이블을 추출하거나 연관된 하위 쿼리를 사용하여 종속성을 생성하는 등 SQL을 다양하게 응용할 수 있습니다.

사용자가 이러한 방법을 통해 쿼리를 작성한다면 SQL로 작성하지 못할 규칙이 없습니다. 마치 일반 프로그램을 개발하듯 여러 형태로 데이터의 결과를 만들 수 있습니다. 위해 설명한 서브쿼리의 실제 사용 예시는 아래를 확인하시기 바랍니다. 

 

SQLD: 서브 쿼리의 활용, Group by절, Merge 구문

 

[SQLD] 서브 쿼리의 활용, Group by절, Merge 구문

이번 포스팅에서는 서브 쿼리의 활용과 Group by절, Merge 구문에 대해 다뤄보도록 하겠습니다. 이전 글에서 서브 쿼리 개념과 종류에 대해 알아봤다면 이번에 실제 활용은 어떻게 하는지를 살펴보

bommbom.tistory.com