자두의 데브로그

[MySQL] 프로그래머스 멸종위기의 대장균 찾기 본문

코딩테스트/SQL

[MySQL] 프로그래머스 멸종위기의 대장균 찾기

왕자두 2024. 10. 10. 19:40

https://school.programmers.co.kr/learn/courses/30/lessons/301651

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

SQL 문제가 이렇게 어려울 수 있나요..

이 문제에서 새롭게 알게 된 것은 "재귀적 쿼리 정의하는 방법"이다.

not in 이나 distinct로 중복되는 값에 대해서 안뽑는 것도 까먹고 있던 개념이지만 ..

 

재귀적 쿼리 정의

WITH RECURSIVE CTE_name (column1, column2, ...) AS (
    -- Anchor member: 재귀 호출의 시작점
    SELECT initial_query
    UNION ALL
    -- Recursive member: 재귀 호출을 반복하는 부분
    SELECT recursive_query
    FROM CTE_name
    WHERE condition
)
SELECT * FROM CTE_name;

 

where 조건을 통해 재귀가 무한 반복되지 않도록 제한하는 것도 중요하다. union all로 첫 번째 쿼리에 대해서 시작하면서 이를 포함해주고, 반복해야되는 내용을 union all 아래에 적는다. 이 문제에서는 세대를 계속해서 증가해줬어야 하므로, 아래의 select 절에서 1로 지정했던 generation에 대해서 +1을 해줌으로써 새롭게 가지고 온 ed1에 대한 parent_id와 tmp의 id가 동일한 경우, 해당 generation을 저장하면 된다. 

-- 코드를 작성해주세요
with recursive tmp as (
    select id, parent_id, 1 as generation
    from ECOLI_DATA
    where parent_id is null
    union all
    select ed1.id, ed1.parent_id, tmp.generation+1
    from tmp
    join ECOLI_DATA ed1
    on tmp.id = ed1.parent_id
)

select count(*) as COUNT, GENERATION
from tmp
where id not in (select distinct parent_id from tmp where parent_id is not null)
group by GENERATION
order by GENERATION;

 

그리고 자식이 없는 대장균의 수이기 때문에 parent_id가 null인 애들을 제외하고 parent_id를 중복 제거하여 뽑았을 때 속하지 않는 값에 대해서만 count를 세면 된다.