[Programmers/mysql] 301651: 멸종위기의 대장균 찾기

songeunm·2024년 9월 3일

PS - sql

목록 보기
5/58
post-thumbnail

문제

Lv. 5 / SELECT, WITH RECURSIVE

문제 흐름

처음에는 단순히 JOIN과 CASE문을 통해서 어떻게 할 수 있지 않을까? 했는데 생각같이 GENERATION컬럼을 만드는게 쉽지 않았다.
그러다 예전에 문제를 풀면서 재귀적으로 번호를 생성하는 쿼리문을 짰던게 생각났다.
뭔가 이걸 잘 이용하면 될 것 같은데..? 하는 생각으로 일단 잘 기억나지 않던 재귀 쿼리에 대해서 찾아봤다.

의미와 사용하는 방법 등을 차례로 알아보는데 역시 예전이다보니 정보가 새로웠다. ^^..
재귀 쿼리는 크게 몇가지만 기억하면 된다.

  1. 재귀적 CTE 생성: WITH RECURSIVE table_name AS처럼 일반 WITH절에 RECURSIVE를 붙인다.
  2. 초기값 설정: SELECT문을 통해서 반복의 기준이 되는 컬럼과 결과과 되는 컬럼을 지정한다.
  3. 유니온: UNION ALL을 통해 초기값을 지정한 테이블과 아래에 쓸 재귀 결과 테이블을 결합한다.
  4. 재귀 설정: 초기값을 지정한 테이블을 다시 불러 기준 컬럼을 이용해 결과 컬럼 값을 업데이트한다.

보통은 4번 과정에서 WHERE절을 통해 재귀의 제한을 만들어주는 것이 일반적인데 이 문제의 경우 제한을 두지 않아도 자연스레 재귀가 끝나게 되어있기 때문에 따로 설정하지 않았다.

코드

/*
멸종위기의 대장균 찾기
SELECT
*/

WITH RECURSIVE CTE AS(
    SELECT  ID,
            PARENT_ID,
            1 AS GENERATION
    FROM ECOLI_DATA
    WHERE PARENT_ID IS NULL
    
    UNION ALL
    
    SELECT  T2.ID,
            T2.PARENT_ID,
            GENERATION+1 AS GENERATION
    FROM CTE AS T1 INNER JOIN ECOLI_DATA T2
    ON T1.ID = T2.PARENT_ID
)

SELECT  COUNT(*) AS "COUNT",
        GENERATION
FROM CTE
WHERE ID NOT IN (
    SELECT DISTINCT PARENT_ID
    FROM ECOLI_DATA
    WHERE PARENT_ID IS NOT NULL
)
GROUP BY 2
ORDER BY 2
;

마무리

오랜만에 풀어본 재귀 쿼리 문제였다.
재귀 쿼리에 대한 내용이 잘 기억나지 않아서 이전에 풀었던 다른 재귀 쿼리 문제도 찾아보고 이론적인 부분만 서치해서 풀어보려고 했는데 결국 다른 분의 풀이를 참고했다. (유사하지만 다른 문제)
그래도 스스로 재귀 쿼리를 풀이로 떠올렸다는 점에 의미를 두기로 했다!
재귀 쿼리 참고 블로그

profile
데굴데굴 구르는 개발자 지망생

0개의 댓글