본문 바로가기
Coding Test/Programmers

[Programmers / MySQL] 특정 세대의 대장균 찾기 (Level 4)

by ngool 2024. 9. 14.

📌 문제

문제 설명

대장균들은 일정 주기로 분화하며, 분화를 시작한 개체를 부모 개체, 분화가 되어 나온 개체를 자식 개체라고 합니다.
다음은 실험실에서 배양한 대장균들의 정보를 담은 ECOLI_DATA 테이블입니다. ECOLI_DATA 테이블의 구조는 다음과 같으며, ID, PARENT_ID, SIZE_OF_COLONY, DIFFERENTIATION_DATE, GENOTYPE 은 각각 대장균 개체의 ID, 부모 개체의 ID, 개체의 크기, 분화되어 나온 날짜, 개체의 형질을 나타냅니다.

 

최초의 대장균 개체의 PARENT_ID 는 NULL 값입니다.

 

문제

3세대의 대장균의 ID(ID) 를 출력하는 SQL 문을 작성해주세요. 이때 결과는 대장균의 ID 에 대해 오름차순 정렬해주세요.

 

예시

예를 들어 ECOLI_DATA 테이블이 다음과 같다면

 

PARENT ID 가 NULL 인 ID 1, ID 2가 1 세대이며 ID 1에서 분화된 ID 3, ID 2에서 분화된 ID 4, ID 5 가 2 세대입니다. ID 4 에서 분화된 ID 6, ID 3에서 분화된 ID 7 이 3 세대이며 ID 6에서 분화된 ID 8은 4 세대입니다.

따라서 결과를 ID 에 대해 오름차순 정렬하면 다음과 같아야 합니다.


📌 나의 풀이

Code

SELECT E1.ID
FROM ECOLI_DATA E1
JOIN ECOLI_DATA E2 ON E1.PARENT_ID = E2.ID
JOIN ECOLI_DATA E3 ON E2.PARENT_ID = E3.ID
WHERE E3.PARENT_ID IS NULL
ORDER BY E1.ID;

 

Solution

1. ECOLI_DATA 테이블(E1)에 ECOLI_DATA 테이블(E2)을 INNER JOIN하되, E1의 PARENT_IDE2의 ID를 키로 하여 두 테이블을 조인

SELECT E1.ID, E1.PARENT_ID, E2.ID, E2.PARENT_ID
FROM ECOLI_DATA E1
JOIN ECOLI_DATA E2 ON E1.PARENT_ID = E2.ID;

E1의 PARENT_ID, E2의 ID로 INNER JOIN된 상태

  • E1의 ID는 모두 누군가의 자식입니다.
  • E1의 PARENT_ID는 모두 누군가의 부모죠.
  • E2의 PARENT_ID는 누군가의 부모의 부모가 됩니다.
  • E2의 PARENT_ID가 없다는 것은 누군가의 부모의 부모가 없다는 것을 의미합니다.
  • 즉, E2의 PARENT_ID가 NULL인 E1의 ID(3, 5, 4)는 정확히 2세대라고 판단할 수 있습니다.

 

2. 위에서 JOIN된 테이블에 대해 ECOLI_DATA 테이블(E3)을 한번더 INNER JOIN하되, E2의 PARENT_ID와 E3의 ID를 키로 하여 두 테이블을 조인

SELECT E1.ID, E1.PARENT_ID, E2.ID, E2.PARENT_ID, E3.ID, E3.PARENT_ID
FROM ECOLI_DATA E1
JOIN ECOLI_DATA E2 ON E1.PARENT_ID = E2.ID
JOIN ECOLI_DATA E3 ON E2.PARENT_ID = E3.ID;

1번에서 만들어진 테이블에서, E2의 PARENT_ID, E3의 ID로 INNER JOIN된 상태

  • E2의 PARENT_ID는 누군가의 부모의 부모입니다.
  • E3의 PARENT_ID는 누군가의 부모의 부모의 부모입니다.
  • E3의 PARENT_ID가 NULL이라는 것은 누군가의 부모의 부모의 부모가 없다는 것을 의미합니다.
  • 즉, E3의 PARENT_ID가 NULL인 E1의 ID(7, 6)는 정확히 3세대라고 판단할 수 있습니다.

 

3. 정확히 3세대인 대장균 ID를 얻기 위해, E3의 PARENT_ID가 NULL인 행만 필터링

 

4. E1의 ID 컬럼 기준으로 오름차순 정렬

 

5. E1의 ID 컬럼만 출력


배운 내용

JOIN이 여러번 필요하다면, 중간 중간 JOIN할 때마다 계속 테이블 상태를 출력해보면서 쿼리를 작성하자!