서브쿼리(SUB QUERY)란 하나의 쿼리(Query = SQL) 안에 포함된 또 다른 쿼리를 이야기한다.

8-1-1. 기준코드 테이블


서브쿼리를 설명하기 위해 기준코드 테이블을 먼저 살펴보자. 기준코드 테이블은 시스템 전반적으로 사용하는 코드 데이터를 관리한다. 공통코드, 마스터코드, 기초코드등 시스템별로 다양한 명칭을 사용한다. 여기서는 기준코드란 명칭을 사용한다. 테이블 구조와 데이터를 살펴보자.

Untitled

-- [SQL-8-1-1-a]
SELECT  *
FROM    startdb.BaseCd;

BaseCdDv       BaseCd  BaseCdNm         SortOrder  
-------------  ------  ---------------  ---------  
EntryResultCd  FAIL    Fail             2          
EntryResultCd  SUCC    Success          1          
HotColdCd      COLD    Cold             2          
HotColdCd      HOT     Hot              1          
ItemSizeCd     BIG     Big Size         2          
ItemSizeCd     REG     Regular Size     1          
MemberGd       GOLD    Gold             2          
MemberGd       PLAT    Platinum         1          
MemberGd       SILV    Silver           3          
MemberSt       ACTV    Active Member    1 
… 생략 …

지금까지 사용한 테이블들의 코드성 컬럼에 대한 정보가 저장되어 있다. 이 기준코드 테이블을 사용해 코드에 대한 값을 가져올 수 있다. 코드 데이터를 구성할 때 코드 값을 001, 002와 같이 무의미하게 구성할 수도 있으며, 위 결과와 같이 COMP(완료), WAIT(대기)와 같이 유의미하게 구성할 수도 있다. 유의미는 코드 자체만으로 의미를 알 수 있는 장점이 있지만, 비즈니스 로직의 추가나 변경으로 코드의 의미가 바뀔 때 큰 곤란을 겪게 된다. 규모가 크고 확장성을 고려한 시스템일수록 유의미보다 무의미 코드 체계가 조금 더 좋은 선택일 수 있다. 우리가 사용중인 startdb는 연습을 목적으로 하기에 유의미 코드 체계를 사용하고 있다. 코드 체계의 유의미, 무의미보다 중요한것은 코드 데이터를 DB화해서 프로세스를 만들어 관리하고 있느냐이다. 코드를 제대로 관리하지 않으면 나중에 데이터를 제대로 해석할 수 없게 되며, 이는 데이터 활용에 큰 어려움을 가져오게 된다.

8-1-2. SELECT 절 서브쿼리


서브쿼리는 SELECT 절과 WHERE 절, 그리고 FROM 절에도 추가해서 사용할 수 있다. 우선은 SELECT 절에 서브쿼리를 사용하는 법을 살펴보자. Shop 테이블의 ShopOperTp와 ShopSt에 대한 코드명을 서브쿼리로 해결하는 예제다.

-- [SQL-8-1-2-a]
SELECT  T1.ShopID ,T1.ShopNm
        ,T1.ShopOperTp
        ,(  SELECT  X.BaseCdNm
            FROM    startdb.BaseCd X
            WHERE   X.BaseCdDv = 'ShopOperTp'
            AND     X.BaseCd = T1.ShopOperTp
         ) ShopOperTp_NM
        ,T1.ShopSt
        ,(  SELECT  X.BaseCdNm
            FROM    startdb.BaseCd X 
            WHERE   X.BaseCdDv = 'ShopSt' 
            AND     X.BaseCd = T1.ShopSt
          ) ShopSt_NM
FROM    startdb.Shop T1
WHERE   T1.ShopId IN ('S001','S002');

ShopID  ShopNm           ShopOperTp  ShopOperTp_NM  ShopSt  ShopSt_NM  
------  ---------------  ----------  -------------  ------  ---------  
S001    New York-1st     FLAG        Flagship       OPEN    Open       
S002    Los Angeles-1st  DIST        Distributor    OPEN    Open 

이처럼 코드에 대한 명칭 처리를 위해 SELECT 절 서브쿼리를 자주 사용한다. SELECT 절에 서브쿼리를 사용할 때는 서브쿼리의 결과 값이 반드시 스칼라(Scalar) 형태가 되어야 한다. 스칼라(Scalar)란 하나의 수치만으로 표시되는 양을 뜻한다. 다시 말해 One-Row, One-Column으로 구성된 단일 값이다. 만약에 SELECT 절 서브쿼리에서 여러 건의 결과나 여러 컬럼의 값을 내보내면 SQL은 에러가 발생하게 된다.

아래와 같이 서브쿼리에서 BaseCd에 대한 조건을 제거하면 SELECT 절 서브쿼리에서 여러 건의 데이터가 추출되면서 에러가 발생한다.