프로그래머스 문제를 풀다가 재귀가 필요한 SQL 문제를 발견했다.
MySQL도 프로그래밍의 재귀처럼 depth를 타고 들어가는 Query를 작성할 수 있다는 것을 새롭게 알게되었다.
기본적으로 With절을 사용하여 임시 테이블을 만들어 호출하는 방식이다. 재귀의 시작점 쿼리와 재귀적으로 호출되는 쿼리가 필요하다. 이 사이엔 합집합 함수를 통해 모든 결과를 포함시킨다. UNION
이 아닌 UNINO ALL
을 사용하는 이유는 중복을 제거하지 않기 위함이다.
WITH RECURSIVE CTE_name AS (
-- Anchor Member: 재귀의 시작점
UNION ALL
-- Recursive Member: 재귀적으로 호출되는 부분
)
-- 결과를 사용하는 부분
SELECT *
FROM CTE_name;
with RECURSIVE generate as(
select ID, 1 as gernerateNum
from ECOLI_DATA
where PARENT_ID is null
union all
select e.id, g.gernerateNum+1
from ECOLI_DATA e join generate g on e.PARENT_ID = g.id
)
select count(*) as COUNT, gernerateNum AS GENERATION
FROM generate g
where g.id not in (select e.parent_id from ECOLI_DATA e where parent_id is not null)
group by gernerateNum
order by gernerateNum;