문제
이 문제는 등급이 RARE인 아이템 중에서 다음 업그레이드 아이템을 출력하는 문제입니다. 위 예시 데이터를 통해 살펴보겠습니다.
- ITEM_ID가 0인 ITEM_A는 PARENT_ITEM_ID가 NULL이기 때문에 루트 아이템이 됩니다.
- ITEM_ID가 1인 ITEM_B는 PARENT_ITEM_ID가 0이기 때문에 ITEM_A에서 ITEM_B로 업그레이드가 가능합니다.
- ITEM_ID가 2인 ITEM_C는 PARENT_ITEM_ID가 0이기 때문에 ITEM_A에서 ITEM_C로 업그레이드가 가능합니다.
- ITEM_ID가 3인 ITEM_D는 PARENT_ITEM_ID가 1이기 때문에 ITEM_B에서 ITEM_D로 업그레이드가 가능합니다.
- ITEM_ID가 4인 ITEM_E는 PARENT_ITEM_ID가 1이기 때문에 ITEM_B에서 ITEM_E로 업그레이드가 가능합니다.
계층도를 통해 살펴보면 다음과 같습니다.
ITEM_D ITEM_E
(RARE) (RARE)
\ /
ITEM_B ITEM_C
(RARE) (REGEND)
\ /
ITEM_A
(RARE)
이 예시 데이터에서 RARITY가 RARE인 아이템은 ITEM_A, ITEM_B, ITEM_D, ITEM_E입니다.
- ITEM_A의 다음 업그레이드 아이템은 ITEM_B와 ITEM_C입니다.
- ITEM_B에서 다음 업그레이드 아이템은 ITEM_D와 ITEM_E입니다.
- ITEM_C는 REGEND이기 때문에 다음 업그레이드 아이템을 고려하지 않습니다.
- ITEM_D는 더 이상 업그레이드할 수 없습니다.
- ITEM_E는 더 이상 업그레이드할 수 없습니다.
따라서 출력되어야 하는 것은 ITEM_B, ITEM_C, ITEM_D, ITEM_E의 ITEM_ID, ITEM_NAME, ITEM_RARITY가 됩니다. 정리하면 ITEM_TREE에서 PARENT_ITEM_ID 값이 있는 RARITY가 RARE인 ITEM_ID에 대한 정보를 출력하면 되는 것입니다.
풀이
- ITEM_ID, ITEM_NAME, ITEM_RARITY를 출력합니다.
- ITEM_ID를 기준으로 내림차순 정렬합니다.
- ITEM_TREE 테이블에서 PARENT_ITEM_ID가 NULL이 아닌 행만 골라내면 다음 업그레이드 아이템을 출력할 수 있습니다.
- ITEM_TREE 테이블의 PARENT_ITEM_ID와 ITEM_INFO 테이블의 ITEM_ID가 일치하는 행을 찾으면 다음 업그레이드 아이템의 정보를 출력할 수 있습니다.
SELECT ITEM_INFO.ITEM_ID, ITEM_INFO.ITEM_NAME, ITEM_INFO.RARITY
FROM ITEM_INFO INNER JOIN ITEM_TREE
ON ITEM_INFO.ITEM_ID = ITEM_TREE.ITEM_ID
WHERE ITEM_TREE.PARENT_ITEM_ID IN (
SELECT ITEM_ID FROM ITEM_INFO
WHERE RARITY = 'RARE'
)
ORDER BY ITEM_ID DESC;
자세히 알아보기
동등 조인, 내부 조인
동등 조인(equi join)과 내부 조인(inner join)은 조건 값이 정확하게 일치할 때 행을 가져오는 조인입니다.
위 풀이를 통해 살펴보면 ITEM_INFO와 ITEM_TREE 테이블에서 ITEM_INFO의 ITEM_ID와 ITEM_TREE의 ITEM_ID가 일치하는 행만 가져와 이 테이블들을 연결합니다.
SELECT I.*, T.PARENT_ITEM_ID
FROM ITEM_INFO I, ITEM_TREE T
WHERE I.ITEM_ID = T.ITEM_ID;
SELECT I.ITEM_ID, I.ITEM_NAME, I.RARITY, I.PRICE, T.PARENT_ITEM_ID
FROM ITEM_INFO AS I
INNER JOIN ITEM_TREE AS T
ON I.ITEM_ID = T.ITEM_ID;
서브 쿼리
서브 쿼리(sub query, nested query)는 SELECT 문 안에 SELECT 문이 기술된 형태의 쿼리입니다. 서브 쿼리의 결과를 상위 쿼리에서 받아 처리합니다.
다중 행 연산자 IN
IN 연산자는 조회하고자 하는 값이 하나일 때만 가능한 = 연산자와 달리 여러 개일 때 사용합니다. 여러 개의 값 목록 중 하나라도 일치하면 조건에 해당하는 결과를 출력합니다.
위 풀이를 통해 살펴보면 ITEM_TREE의 PARENT_ITEM_ID가 서브 쿼리를 통해 얻은 ITEM_INFO의 ITEM_ID 값 목록 중 하나와 일치하는 행만 ITEM_INFO와 ITEM_TREE를 동등 조인한 테이블 가져오게 됩니다.