📌 문제
문제 설명
대장균들은 일정 주기로 분화하며, 분화를 시작한 개체를 부모 개체, 분화가 되어 나온 개체를 자식 개체라고 합니다.
다음은 실험실에서 배양한 대장균들의 정보를 담은 ECOLI_DATA 테이블입니다. ECOLI_DATA 테이블의 구조는 다음과 같으며, ID, PARENT_ID, SIZE_OF_COLONY, DIFFERENTIATION_DATE, GENOTYPE 은 각각 대장균 개체의 ID, 부모 개체의 ID, 개체의 크기, 분화되어 나온 날짜, 개체의 형질을 나타냅니다.
최초의 대장균 개체의 PARENT_ID 는 NULL 값입니다.
문제
대장균 개체의 ID(ID)와 자식의 수(CHILD_COUNT)를 출력하는 SQL 문을 작성해주세요. 자식이 없다면 자식의 수는 0으로 출력해주세요. 이때 결과는 개체의 ID 에 대해 오름차순 정렬해주세요.
예시
예를 들어 ECOLI_DATA 테이블이 다음과 같다면
ID 1인 개체의 자식은 ID 3으로 1개 ID 2인 개체의 자식은 ID 4,5 로 2개 ID 4인 개체의 자식은 ID 6으로 1개이며 나머지 개체들은 자식이 없으므로 ID 에 대해 오름차순 정렬하면 결과는 다음과 같아야 합니다.
📌 나의 풀이
Code
SELECT ID,
IFNULL(
(SELECT COUNT(*)
FROM ECOLI_DATA
GROUP BY PARENT_ID
HAVING PARENT_ID = ID
), 0
) AS CHILD_COUNT
FROM ECOLI_DATA;
Solution
1. ECOLI_DATA에서 ID와 서브쿼리를 통해 만들 CHILD_COUNT 컬럼을 선택하기
- CHILD_COUNT는 IFNULL 함수를 적용해서 NULL 값은 0으로 대체되도록 함
2. IFNULL 함수의 첫번째 인자로 들어갈 서브쿼리 작성하기
- ECOLI_DATA 테이블에서 각 PARENT_ID를 기준으로 그룹화
- HAVING PARENT_ID = ID를 사용하여, 현재 ID와 일치하는 PARENT_ID를 가진 행들만 필터링
- COUNT(*)를 사용해 각 그룹에 속하는 자식 행의 개수 가져오기
📌 다른 사람의 풀이
Code
SELECT ID, IFNULL(CNT, 0) AS CHILD_COUNT
FROM ECOLI_DATA AS A
LEFT JOIN(
SELECT PARENT_ID, COUNT(PARENT_ID) AS CNT
FROM ECOLI_DATA
GROUP BY PARENT_ID) AS B
ON A.ID = B.PARENT_ID
ORDER BY ID
Solution
1. ECOLI_DATA 테이블에 LEFT JOIN할 서브쿼리 만들기
- ECOLI_DATA 테이블에서 PARENT_ID 컬럼 기준으로 그룹화하고, PARENT_ID 컬럼과, 각 그룹 내 행의 개수(CNT)만 가져오기
2. 서브쿼리를 ECOLI_DATA 테이블에 LEFT JOIN하되, 원래 테이블의 ID 컬럼과 서브쿼리의 PARENT_ID 컬럼을 기준으로 조인
3. ID를 기준으로 오름차순 정렬
4. 원래 테이블의 ID, 그리고 서브쿼리의 CNT 컬럼만 가져오되, CNT 컬럼은 NULL이 있는 경우 0으로 대체
배운 내용
부모 자식 관계에 대한 문제를 풀 때에는 서브쿼리를 만든 뒤 LEFT JOIN을 고려하자
'Coding Test > Programmers' 카테고리의 다른 글
[Programmers / MySQL] 대장균의 크기에 따라 분류하기 2 (Level 3) (1) | 2024.09.13 |
---|---|
[Programmers / MySQL] 대장균의 크기에 따라 분류하기 1 (Level 3) (1) | 2024.09.12 |
[Programmers / MySQL] 특정 형질을 가지는 대장균 찾기 (Level 1) (0) | 2024.09.10 |
[Programmers / MySQL] 오프라인/온라인 판매 데이터 통합하기 (Level 4) (0) | 2024.09.03 |