[프로그래머스/MySQL/SELECT/LV.2] 부모의 형질을 모두 가지는 대장균 찾기

sammy·2026년 2월 27일

SQL 문제풀이

목록 보기
85/87

🧩 문제

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


📌 문제 설명

대장균 개체 테이블에서 “자식이 부모의 형질(비트마스크)을 모두 포함하는” 개체만 골라 ID, 자식 형질, 부모 형질을 출력하는 문제입니다.

  • ECOLI_DATA는 대장균 개체의 기본 정보와 유전 형질(GENOTYPE)을 정수 비트마스크로 저장합니다.
  • PARENT_ID가 NULL이면 최초 개체(부모 없음)이며, 그 외에는 부모를 참조합니다.
  • 부모의 형질을 “모두 보유”는 비트 관점에서 부모 비트가 자식에 전부 켜져 있어야 함을 뜻합니다.

📂 테이블 구조 (또는 입력 형식)

Column nameTypeNullable
IDINTEGERFALSE
PARENT_IDINTEGERTRUE
SIZE_OF_COLONYINTEGERFALSE
DIFFERENTIATION_DATEDATEFALSE
GENOTYPEINTEGERFALSE

🎯 문제 목표

부모의 형질을 모두 보유한 대장균의 정보를 출력합니다.

  • 출력 컬럼: ID, GENOTYPE, PARENT_GENOTYPE(부모의 GENOTYPE)
  • 조건: 부모가 존재해야 하며(PARENT_ID IS NOT NULL), 자식이 부모의 형질을 모두 포함해야 함
  • 정렬: ID 오름차순

🧠 문제 접근 (Approach)

  1. 부모-자식 관계를 Self Join으로 구성합니다.
    ECOLI_DATA 테이블을 자식(ED1)과 부모(ED2)로 나누어 생각하고, ED1.PARENT_ID = ED2.ID 조건으로 부모 레코드를 연결합니다.

  2. 부모가 없는 개체는 제외합니다.
    최초 개체는 PARENT_ID가 NULL이므로 비교 대상이 없어 조건을 판단할 수 없습니다.
    따라서 WHERE ED1.PARENT_ID IS NOT NULL로 부모가 존재하는 행만 남깁니다.

  3. 비트 연산으로 “부모 형질을 모두 포함” 여부를 판별합니다.
    형질은 정수 비트마스크이므로, (ED1.GENOTYPE & ED2.GENOTYPE) = ED2.GENOTYPE이면 부모의 1비트들이 자식에서도 모두 1이라는 뜻입니다.
    이 조건을 만족하는 자식만 필터링합니다.

  4. 요구 정렬 조건을 적용합니다.
    결과는 ORDER BY ED1.ID ASC로 ID 오름차순 정렬합니다.

👉 핵심 아이디어 한 줄 요약
Self Join으로 부모 GENOTYPE을 가져온 뒤, (자식 & 부모) = 부모 조건으로 포함 관계를 검사합니다.


✅ 내 정답

SELECT ED1.ID, ED1.GENOTYPE, ED2.GENOTYPE PARENT_GENOTYPE
FROM ECOLI_DATA ED1 LEFT JOIN ECOLI_DATA ED2
ON ED1.PARENT_ID = ED2.ID
WHERE ED1.PARENT_ID IS NOT NULL
AND (ED1.GENOTYPE & ED2.GENOTYPE = ED2.GENOTYPE)
ORDER BY ED1.ID ASC;

⚠️ AI 코드 리뷰

SELECT
  C.ID,
  C.GENOTYPE,
  P.GENOTYPE AS PARENT_GENOTYPE
FROM ECOLI_DATA C
JOIN ECOLI_DATA P
  ON C.PARENT_ID = P.ID
WHERE (C.GENOTYPE & P.GENOTYPE) = P.GENOTYPE
ORDER BY C.ID ASC;

코드리뷰 포인트

  • LEFT JOIN을 쓰고 WHERE C.PARENT_ID IS NOT NULL로 거르는 방식은, 논리적으로 INNER JOIN과 동일한 결과가 되므로 JOIN이 더 의도가 명확합니다. (부모가 반드시 있어야 하니까요.)
  • 비트 조건은 C.GENOTYPE & P.GENOTYPE = P.GENOTYPE처럼 써도 동작하는 DB가 많지만, 가독성과 우선순위 오해 방지를 위해 (C.GENOTYPE & P.GENOTYPE) = P.GENOTYPE처럼 괄호를 권장합니다.
  • 별칭을 ED1/ED2 대신 C/P(Child/Parent)로 두면 더 빨리 이해하기 좋습니다.

짚고가기

  • 비트마스크에서 “부모의 형질을 모두 포함”은 부분집합 검사이고, SQL에선 (자식 & 부모) = 부모로 표현합니다.
  • 부모가 없는 행(PARENT_ID IS NULL)은 조인 자체가 성립하지 않으므로, 이 문제에선 JOIN이 자연스럽습니다.
profile
누군가에게 도움을 주기 위한 개발자로 성장하고 싶습니다.

0개의 댓글