문제
코딩테스트 연습 - 특정 세대의 대장균 찾기 | 프로그래머스 스쿨
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
풀이 - 단순하게 푸는 방식
WITH FIRST_CTE AS (
SELECT ID
FROM ECOLI_DATA
WHERE PARENT_ID IS NULL
),
SECOND_CTE AS (
SELECT ID
FROM ECOLI_DATA
WHERE PARENT_ID IN (SELECT * FROM FIRST_CTE)
)
SELECT ID
FROM ECOLI_DATA
WHERE PARENT_ID IN (SELECT * FROM SECOND_CTE)
ORDER BY ID
이 문제는 결국 쿼리를 계층형으로 여러 번 실행시킨 뒤에 찾아야 한다.
여기서 알아야 하는 개념이 바로 Common Table Expression(CTE)이다.
CTE는 임시 결과 테이블을 만드는 것이다.
WITH이라는 키워드를 사용해서 만들면 된다.
여기서는 FIRST_CTE를 만들고 그 다음 SECOND_CTE를 만든다.
그러면 어떻게 푸는지 보면 다음과 같다.
결국 3세대의 대장균의 찾는다는 말은 PARENT_ID를 3번 타고 들어간 값을 찾는 것이다.
그러면 먼저 1세대 대장균을 찾는다.
WITH FIRST_CTE AS (
SELECT ID
FROM ECOLI_DATA
WHERE PARENT_ID IS NULL
),
문제 예시에서 NULL이 1세대라고 했으므로 FIRST_CTE에 NULL인 것을 찾아서 넣어둔다.
SECOND_CTE AS (
SELECT ID
FROM ECOLI_DATA
WHERE PARENT_ID IN (SELECT * FROM FIRST_CTE)
)
그 뒤엔 FIRST_CTE에서 찾은 ID 값들을 PARENT_ID로 가지고 있는 행들을 SECOND_CTE에 저장한다.
in 키워드는 in 안에 들어있는 값 중 하나라도 들어있으면 그 행을 반환한다.
예를 들어, where id in (1,2,3,4) 이렇게 한다면, id가 1,2,3,4 중에 하나인 행들을 반환한다.
이렇게 FIRST_CTE와 SECOND_CTE 임시 테이블을 만들었다.
그러면 3세대는 어떻게 찾을까?
간단하다.
SELECT ID
FROM ECOLI_DATA
WHERE PARENT_ID IN (SELECT * FROM SECOND_CTE)
ORDER BY ID
SECOND_CTE이 가지고 있는 PARENT_ID에 속하는 값을 찾으면 그만이다.
풀이 - 재귀를 이용해서 푸는 방식
WITH RECURSIVE Hierarchy_CTE AS (
-- 초기 루트 노드 선택
SELECT ID, PARENT_ID, 1 AS LEVEL
FROM ECOLI_DATA
WHERE PARENT_ID IS NULL
UNION ALL
-- 재귀적으로 자식 노드 찾기
SELECT E.ID, E.PARENT_ID, H.LEVEL + 1
FROM ECOLI_DATA E
INNER JOIN Hierarchy_CTE H ON E.PARENT_ID = H.ID
)
SELECT ID
FROM Hierarchy_CTE
WHERE LEVEL = 3 -- 원하는 계층 선택
ORDER BY ID;
프로그래밍 언어에 있는 재귀 함수와 비슷한 역할을 하는 WITH RECURSIVE이다.
SELECT ID, PARENT_ID, 1 AS LEVEL
FROM ECOLI_DATA
WHERE PARENT_ID IS NULL
위 부분은 Anchor Query 라고 하고 초기 값을 설정하는 곳이다.
UNION ALL
위 키워드로 재귀하고 초기값이 갈린다고 보면 된다.
결국 계속해서 UNION 연산을 진행하게 되는데, ALL을 사용하면 중복 제거를 할 수 있다.
SELECT E.ID, E.PARENT_ID, H.LEVEL + 1
FROM ECOLI_DATA E
INNER JOIN Hierarchy_CTE H ON E.PARENT_ID = H.ID
이 부분은 계속해서 불러와지는 쿼리로
H.LEVEL + 1을 한 뒤, 아까처럼 PARENT_ID를 비교하여 자식을 찾는다.
그렇게 모든 테이블이 만들어지게 된다.
SELECT ID
FROM Hierarchy_CTE
WHERE LEVEL = 3 -- 원하는 계층 선택
ORDER BY ID;
그 뒤에 레벨을 필터링하면 결과값이 완성된다.
참고로 재귀 부분을 모두 진행하게 되면 다음과 같은 테이블이 만들어진다.
여기서 level = 3만 가져가면 우리가 원하는 값을 구할 수 있게 된다.
'DB > SQL' 카테고리의 다른 글
[SQL]가격이 제일 비싼 식품의 정보 출력하기 - SQL 고득점 Kit (0) | 2025.02.13 |
---|---|
[SQL]재구매가 일어난 상품과 회원 리스트 구하기 - SQL 고득점 Kit (0) | 2025.02.13 |
[SQL]서울에 위치한 식당 목록 출력하기 - SQL 고득점 Kit (0) | 2025.02.12 |
[SQL]3월에 태어난 여성 회원 목록 출력하기 - SQL 고득점 Kit (0) | 2025.02.11 |
[SQL]평균 일일 대여 요금 구하기 - SQL 고득점 Kit (0) | 2025.02.11 |