SQL

[ SQL ] SQL 트리형 구조 테이블 ( WITH CTE ··· ) 을 활용해보자

menus 2024. 6. 6. 16:16
728x90

 

 

안녕하세요 !   😃

 

오늘은 트리형 구조를 가진 테이블에 대해서 공부 해볼 건데요.

 

기본적인 함수들은 한번 다룬적이 있으니 기본 함수 내용은 아래 글을 참조해주시면 될 것 같습니다.

 

 

[ORACLE] 오라클 SQL 함수 정리

안녕하세요 ! (^∀^●)ノシ 오늘은 지난 글에 이어서 ORACLE SQL에 대해서 배워보겠습니다. ORACLE SQL에는 다양한 함수가 있는데, 자주 사용되는 함수들을 위주로 정리해보도록 하겠습니다 ! 문

preparingforme-n-us.tistory.com

 


 

트리형 구조를 가진 테이블은 주로 어디에 쓰일까요?

 

트리 구조로 나타날 수 있는 데이터들을 관리할 때 쓸 수 있습니다.

 

예를 들면,

 

  서울시 성남시
강서구, 송파구, 강남구, 관악구 ... 수정구, 분당구 ...
화곡동, 마곡동, 개화동 분당동, 수내 1동, ...

 

위와 같은 데이터를 서울시, 성남시를 상위 노드로 본다면 구가 하위 노드, 구의 하위 노드는 동으로 볼 수 있겠죠.

 

region이라는 테이블을 생성한다고 봤을 때, 다음과 같이 넣을 수 있겠습니다.

 

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 1, '서울시', '');

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 2, '성남시', '');

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 11, '강서구', 1);

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 12, '송파구', 1);

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 13, '수정구', 2);

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 14, '분당구', 2);

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 101, '화곡동', 11);

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 102, '마곡동', 11);

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 103, '분당동', 14);

INSERT INTO REGION ( regionNo, regionNm, hirnkRegionNo ) VALUES( 104, '수내 1동', 14);

 

테이블 안에 지역 번호, 지역 이름, 상위 지역 번호가 있다고 하면 해당 데이터를 저장할 때도, 불러올때도 쉽게 이해할 수 있습니다.

 

위와 같은 트리 구조의 테이블이 있을 때 최하위인 '동' 데이터들을 가져오는 방법은 다음과 같습니다.

 

SELECT C.regionNo, C.regionNm 
FROM REGION A
    LEFT OUTER JOIN REGION B ON A.regionNo = B.hirnkRegionNo
    LEFT OUTER JOIN REGION C ON B.regionNo = C.hirnkRegionNo
WHERE C.hirnkRegionNo IS NOT NULL;

 

 

쿼리를 실행시켰을 때 얻을 수 있는 데이터는 다음과 같습니다.

 

 

 

트리 구조의 테이블을 다루는 것에 익숙해져봅시다 !

 

이렇게 계층 구조를 가진 테이블을 다룰 때, 노드의 깊이가 10 이상이 되면 어떻게 조회하면 될까요?

 

위에 작성한 쿼리처럼  LEFT OUTER JOIN을 여러 문장에 걸쳐 쓰는 게 어려워질 수 있는데,

 

트리의 노드 깊이가 깊어지면 RECURSIVE를 사용하면 간결하게 작성할 수 있어서 반복 작업을 피할 수 있습니다 !!

 

RECURSIVE는 WITH 를 사용하여 작성해주게되는데.. 지금은 노드 깊이가 3이지만 쿼리문을 작성해볼까요?

 

WITH CTE (regionNo, regionNm, hirnkRegionNo, depth)
AS(
    SELECT A.regionNo, A.regionNm, A.hirnkRegionNo, 1 depth
    FROM REGION A
    UNION ALL
    SELECT A.regionNo, A.regionNm, A.hirnkRegionNo, B.depth + 1
    FROM REGION A
    INNER JOIN CTE B ON B.regionNo = A.hirnkRegionNo
)
SELECT * FROM CTE ORDER BY depth;

 

 

위 쿼리문을 실행하면 가장 부모 노드인 데이터들이 depth 1 로 표현되고 가장 하위 노드인 데이터들은 depth 3으로 표현됩니다.

 

출력된 데이터를 보면

 

 

 

다음과 같으며 그럼 가장 하위 노드를 출력하려면 어떻게 해야할까요 ?

 

작성된 ORDER BY 대신 WHERE 절을 써서 depth = 3 인 데이터를 가져오면 되겠습니다.

 

자, 이렇게 오늘은 트리 형 구조를 가지는 테이블에 대해서 알아보았습니다 !

 

다음 글에서도 유용하고 유익한 정보를 가져오도록 하겠습니다.

 

 

 

감사합니다 !