본문 바로가기
코딩테스트

[프로그래머스 - mysql / 5단계] 멸종위기의 대장균 찾기

by 럭키봇 2024. 6. 19.
문제

 

[문제 설명]
각 세대별 자식이 없는 개체의 수(COUNT)와 세대(GENERATION)를 출력하는 SQL문을 작성해주세요. 이때 결과는 세대에 대해 오름차순 정렬해주세요. 단, 모든 세대에는 자식이 없는 개체가 적어도 1개체는 존재합니다.

 

자세한 문제는 아래 출처 클릭해주세요.

 

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

 

 

 

 


 

 

 

예시

 

입출력 예 #1

각 세대별 대장균의 ID는 다음과 같습니다.
1 세대 : ID 1, ID 2
2 세대 : ID 3, ID 4, ID 5
3 세대 : ID 6, ID 7
4 세대 : ID 8

 

이 때 각 세대별 자식이 없는 대장균의 ID는 다음과 같습니다.
1 세대 : ID 1
2 세대 : ID 3, ID 5
3 세대 : ID 7
4 세대 : ID 8

 

따라서 결과를 세대에 대해 오름차순 정렬하면 다음과 같아야 합니다.
COUNT  GENERATION
1               1
2               2
1               3
1               4

 

 

 


 

 

 

풀이

 

# # -- 코드를 작성해주세요
WITH RECURSIVE PATH(ID, PARENT_ID, GENERATION) AS (
    SELECT ID, PARENT_ID, 1
    FROM ECOLI_DATA
    WHERE PARENT_ID IS NULL
    UNION ALL
    SELECT E.ID, E.PARENT_ID, P.GENERATION + 1
    FROM ECOLI_DATA E
    INNER JOIN PATH P ON P.ID = E.PARENT_ID
)

SELECT COUNT(GENERATION) AS 'COUNT', GENERATION FROM PATH WHERE ID NOT IN
(SELECT PARENT_ID FROM ECOLI_DATA WHERE PARENT_ID IS NOT NULL GROUP BY PARENT_ID )
GROUP BY GENERATION ORDER BY GENERATION;

 

1. 재귀적인 쿼리를 수행하기 위해 RECURSIVE 함수를 사용하였다.

 

2. UNION ALL 기준으로 첫번째 SELECT 문에서는 재귀 쿼리의 시작점을 정의하였다.

최상위 데이터인 PARENT_ID가 NULL인 데이터를 선택한다.

 

3. UNION ALL 기준으로 두번째 SELECT 문에서는 첫번째 쿼리문과 결합하여 재귀적으로 데이터를 조회한다.

INNER JOIN 을 사용하여 상위 데이터의 하위 데이터를 찾는다.

 

4. GENERATION을 하나씩 증가시킨다.

 

5. 서브쿼리에서는 부모가 있는 노드를 선택한다.

 

6. 서브쿼리에서는 ID 가 서브쿼리에 선택된 PARENT_ID에 포함되지 않는 노드를 선택한다.

즉, 최종 노드를 의미한다.

 

7. 각 세대에 속한 자식이 없는 세대의 개수를 계산하고 세대별로 오름차순하여 정렬한다.