← 개념서모바일 버전
2과목 · SQL 기본 및 활용·14

계층형 질의

Oracle의 CONNECT BY, 레벨 함수, 표준 재귀 CTE까지 계층형 조회를 정리합니다.

1. 계층형 데이터란

부모-자식 관계가 같은 테이블 안에 반복되는 구조. 사원-상사, 카테고리-하위 카테고리, 조직도, 폴더 트리.

예) emp(emp_id, name, manager_id) — manager_id는 같은 테이블의 emp_id를 참조.

2. Oracle CONNECT BY

SELECT LEVEL,
       LPAD(' ', (LEVEL-1)*2) || name AS tree,
       CONNECT_BY_ROOT name AS root,
       SYS_CONNECT_BY_PATH(name, '/') AS path,
       CONNECT_BY_ISLEAF AS is_leaf
FROM   emp
START WITH manager_id IS NULL       -- 루트 조건
CONNECT BY PRIOR emp_id = manager_id; -- 부모 → 자식 방향

키워드 정리

키워드 의미
START WITH 루트 행 조건
CONNECT BY 부모-자식 관계식
PRIOR 이전(부모) 행의 값
LEVEL 루트에서의 깊이 (1부터)
CONNECT_BY_ROOT col 루트 행의 값
SYS_CONNECT_BY_PATH(col, delim) 루트부터의 경로
CONNECT_BY_ISLEAF 리프면 1, 아니면 0
CONNECT_BY_ISCYCLE 순환 감지 (NOCYCLE 옵션 필요)

ORDER SIBLINGS BY

형제 노드 간 정렬을 유지하며 트리 구조를 보존.

SELECT LEVEL, name FROM emp
START WITH manager_id IS NULL
CONNECT BY PRIOR emp_id = manager_id
ORDER SIBLINGS BY name;

3. 방향의 차이: 부모→자식 vs 자식→부모

  • 부모 → 자식 (하향): CONNECT BY PRIOR emp_id = manager_id
  • 자식 → 부모 (상향): CONNECT BY PRIOR manager_id = emp_id

PRIOR가 붙은 쪽이 이미 방문한(앞 행) 컬럼입니다.

4. 표준 SQL — 재귀 CTE (WITH RECURSIVE)

Oracle 외 대부분 DBMS (PostgreSQL, MySQL 8+, SQL Server)는 재귀 CTE를 씁니다.

WITH RECURSIVE tree AS (
  -- 앵커: 루트 행
  SELECT emp_id, name, manager_id, 1 AS lvl, CAST(name AS TEXT) AS path
  FROM emp
  WHERE manager_id IS NULL

  UNION ALL

  -- 재귀: 자식을 붙임
  SELECT e.emp_id, e.name, e.manager_id, t.lvl + 1, t.path || '/' || e.name
  FROM emp e
  JOIN tree t ON e.manager_id = t.emp_id
)
SELECT * FROM tree ORDER BY path;

5. 출력 팁

들여쓰기로 시각적 트리 출력:

LPAD(' ', (LEVEL - 1) * 2) || name

순환(사이클) 방지:

CONNECT BY NOCYCLE PRIOR emp_id = manager_id;

6. CONNECT_BY_ISCYCLE의 오해

  • CONNECT_BY_ISCYCLE현재 행의 자식이 이미 방문된 조상인지 여부를 알려준다. 즉 "순환 노드"에서 1.
  • 단순히 "루트까지 경로"를 표시하는 것이 아님. 시험 선택지에서 "ROOT까지의 경로에 존재하는 데이터"로 설명하면 오답.

7. 자주 출제되는 포인트

  • LEVEL은 1부터 시작.
  • CONNECT_BY_ISLEAF: LEAF면 1, 아니면 0. (0/1 방향 주의)
  • SYS_CONNECT_BY_PATH: 루트부터의 경로.
  • PRIOR 위치로 방향을 결정.
  • 표준 SQL은 WITH RECURSIVE.

8. 요약 체크리스트

  • CONNECT BY 키워드와 함수를 구분해 사용할 수 있다.
  • 부모→자식 / 자식→부모 방향을 PRIOR로 제어할 수 있다.
  • WITH RECURSIVE로 같은 결과를 낼 수 있다.
  • ISLEAF / ISCYCLE의 의미를 정확히 안다.