DB

CTE(공통 테이블 식) (MS-SQL)

이안_ian 2019. 7. 18. 14:52
반응형

ms-sql에는 재귀함수와 같은 역할을 하는 문법이 존재한다.

이는 단순 쿼리에서 파생되며 단일 select, insert, update, delete 또는 merge문 실행 범위 내에서 정의됨

CTE는 비재귀적 CTE와 재귀적 CTE로 구분 할 수 있습니다.

 

재귀적이라는 의미는 자기 자신을 반복적으로 호출하는 것을 의미합니다. (BOM, 부서계층그룹에 해당)

비재귀적은 단순한 형태의 쿼리를 얘기하며, 복잡한 쿼리 문장을 단순화 시키는데 적합하게 사용될 수 있습니다.

 

기본 문법

;WITH CTE_테이블이름(열이름)
AS
(
    <SELECT 쿼리문>
)
SELECT 열이름 FROM CTE_테이블이름;

WITH 키워드 다음에는 CTE의 이름을 지정하고 그 다음에는 선택적인 열 별칭 목록을 지정합니다.

열 별칭은 CTE 내의 select문에서 반환하는 열에 해당합니다.

선택적인 열 별칭 다음에 필수 항목인 AS 키워드를 지정합니다.

그리고 AS 키워드 다음에는 CTE를 정의하는 쿼리식을 괄호로 감싸고 지정합니다.

 

예시

USE ACCT_AC;
;WITH CTE_SAMPLE(GYE_CODE,GYE_DES)
AS
(
    SELECT GYE_CODE,GYE_DES FROM ACC002
)
SELECT * FROM CTE_SAMPLE;

재귀적 예제

기본 데이터 생성

CREATE TABLE SAMPLE_CTE1
(
  GRP VARCHAR(4) NOT NULL PRIMARY KEY,
  GRP_DES NVARCHAR(10),
  PARENT_GRP VARCHAR(4)
);

INSERT INTO SAMPLE_CTE1(GRP,GRP_DES,PARENT_GRP) VALUES
('01','한국',NULL),('02','서울본사','01'),('03','개발본부','02'),('04','개발팀','03');

기본 문법

;WITH CTE_테이블이름(열이름)
AS(
    <쿼리문1: SELECT * FROM 테이블A>
    UNION ALL
    <쿼리문2: SELECT * FROM 테이블B JOIN CTE_테이블이름>
)
SELECT * FROM CTE_테이블이름;

위의 구문에서 <쿼리문1>을 앵커 멤버<Anchor Member)라고 부르고, <쿼리문2>를 재귀멤버<Recursive Member>라고 칭한다.

 

1. <쿼리문1>을 실행한다. 이것이 루틴의 최초 호출에 해당한다. 그리고, 기본값은 0으로 초기화된다.

2. <쿼리문2>를 실행한다. 기본값을 기본값+1로 증가시킨다. 그런데 select의 결과가 빈값이 아니라면, 'CTE_테이블이름'을 다시 재귀적으로 호출한다.

3. 계속 2번을 반복한다. select의 결과가 아무것도 없다면 재귀적인 호출이 중단된다.

4. 외부의 select문을 실행해서 앞 단계에서의 누적된 결과(union all)를 가져온다.

 

쿼리구현

;WITH CTE(GRP,GRP_DES,PARENT_GRP,LVL)
AS
(
       -- 찾고자하는기준이되는그룹정보를조회
       SELECT GRP,GRP_DES,PARENT_GRP,0 AS LVL
       FROM SAMPLE_GROUP1
       WHERE GRP = '01'
       UNION ALL
       -- 위에서찾은기준을가지고그룹의상위정보를가지고옴
       SELECT A.GRP,A.GRP_DES,A.PARENT_GRP,LVL+1
       FROM SAMPLE_GROUP1 A
              INNER JOIN CTE B
                     ON A.PARENT_GRP = B.GRP
)
SELECT GRP,GRP_DES,PARENT_GRP,LVL FROM CTE
ORDER BY LVL;
반응형