기본 패턴
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