PostgreSQL집계와 분석

recursive CTE 기본

조직도나 카테고리 트리처럼 계층 구조를 단계적으로 따라 내려가야 할 때 쓰는 recursive CTE의 기본 흐름을 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

sql
WITH RECURSIVE category_tree AS (
  SELECT id, parent_id, name, 1 AS depth
  FROM categories
  WHERE parent_id IS NULL

  UNION ALL

  SELECT c.id, c.parent_id, c.name, ct.depth + 1
  FROM categories c
  JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT *
FROM category_tree;

설명

  • recursive CTE는 "현재 단계 결과를 다음 단계 입력으로 다시 사용"하는 쿼리 패턴입니다. 계층 구조를 SQL만으로 순회할 수 있게 해 줍니다.
  • 구조는 보통 두 부분으로 나뉩니다. 시작점(anchor query)과, 그 결과를 반복 확장하는 recursive member입니다. UNION ALL로 두 부분을 연결합니다.
  • 대표적인 사용처는 조직도, 댓글 트리, 카테고리 구조, 메뉴 계층, 상하위 관계 탐색입니다. 애플리케이션 코드로 여러 번 쿼리하는 대신 DB 한 번에 가져오고 싶을 때 유용합니다.
  • 다만 recursive CTE는 읽기 난이도가 높고, 무한 루프성 데이터가 있으면 위험해질 수 있습니다. 그래서 depth 컬럼을 두거나 종료 조건을 더 분명히 관리하는 편이 좋습니다.
  • 이 기능은 "SQL로도 반복 구조를 표현할 수 있다"는 감각을 줍니다. 하지만 모든 트리를 무조건 recursive CTE로 풀기보다, 읽기 난이도와 쿼리 비용을 함께 보아야 합니다.

빠른 정리

구성 요소역할
anchor query시작점
recursive member다음 단계 확장
UNION ALL두 단계 연결
잘 맞는 곳조직도, 트리, 계층 메뉴

주의할 점

계층 데이터에 순환 참조가 있거나 종료 조건이 불분명하면 recursive CTE가 예상보다 무겁거나 위험해질 수 있습니다. depth 추적과 데이터 무결성 검사가 중요합니다.

참고 링크

1 sources