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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

코드설명

INNER JOIN + NESTED SUBQUERY + IN 을 활용합니다.

 

문제이해가 상당히 어렵습니다.

 

로직을 간단히 설명하겠습니다.

 

1. ITEM_INFO와 ITEM_TREE를 INNER JOIN 하여, 아래와 같은 구조를 만들어줍니다.

 

ITEM_ID    ITEM_NAME                           RARITY                                     PRICE                 ITEM_ID PARENT_ITEM_ID

0 ITEM_A RARE 10000 0 null
1 ITEM_B RARE 9000 1 0
2 ITEM_C LEGEND 11000 2 0
3 ITEM_D RARE 10000 3 1
4 ITEM_E RARE 12000 4 1

 

왜 위와 같은 JOIN을 할까요?

ITEM_TREE의 COLUMN 값은 ITEM_ID와 PARENT_ITEM_ID 로 이루어져있습니다. 즉, ITEM_ID와 데이터가 연관되어있다는 것 입니다.

만약, ITEM_TREE의 값에 추가적인 COLUMN 들이 존재한다고 하면 어떻게 할것인가? 라는 고민이 생길 수 있습니다.

해당 부분은 문제 조건에서, 각 아이템들은 "단, 각 아이템들은 오직 하나의 PARENT 아이템 ID를 가지며, ROOT 아이템의 PARENT 아이템 ID는 NULL 입니다." 라는 조건이 있습니다. 

알고리즘으로 따지자면, 단순 TREE 입니다.

 

2.. 위의 INNER JOIN을 통해 데이터를 만들었다면, PARENT_ITEM_ID가 'RARE'인 것을 골라내야 합니다.

WHERE절에 SUBQUERY가 존재하는 NESTED SUBQUERY 를 활용하여, 해당사항을 해결합니다.

매번, 하나의 레코드가 만들어질떄마다 서브쿼리가 실행된다는 점이 비효율적으로 보이나, 다른 방법으로도 이 방법은 피할 수 없는 방법으로 보입니다.

아래와 같이 현재 레코드의 PARENT_ITEM_ID가 ITEM_ID인것을 찾아서 RARITY가 'RARE'인 것을 찾아나갑니다.

WHERE 
    IT1.PARENT_ITEM_ID = 
        ( SELECT ITEM_ID FROM ITEM_INFO WHERE  ITEM_ID = IT1.PARENT_ITEM_ID AND RARITY = 'RARE')

 

이때 IN을 활용할 수도 있습니다. PARENT_ITEM_ID IN ( RARE인 아이템들의 ITEM_ID) 을 통하여서 ITEM_TREE에 주어진 각 ITEM들 중 부모가 RARE인것을 가져올 수 있습니다.

EQUAL(=)로 해도 됩니다.

 

PARENT_ITEM_ID가 NULL인 아이템은 ROOT 아이템으로써, 시작점이기에 무시됩니다.

코드

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_INFO.ITEM_ID DESC;

 

INLINE-VIEW 안의 쿼리를 좀 더 특정시켰습니다. (ITEM_ID = IT1.PARENT_ITEM_ID)

SELECT 
    II1.ITEM_ID AS ITEM_ID,
    II1.ITEM_NAME AS ITEM_NAME,
    II1.RARITY AS RARITY
FROM ITEM_INFO AS II1
    INNER JOIN ITEM_TREE AS IT1
    ON II1.ITEM_ID = IT1.ITEM_ID
WHERE 
    IT1.PARENT_ITEM_ID = 
        ( SELECT ITEM_ID FROM ITEM_INFO WHERE  ITEM_ID = IT1.PARENT_ITEM_ID AND RARITY = 'RARE')
ORDER BY IT1.ITEM_ID DESC

 

3중 INNER JOIN문으로 푼 코드입니다.

SELECT II2.ITEM_ID, II2.ITEM_NAME, II2.RARITY
FROM ITEM_INFO AS II
INNER JOIN ITEM_TREE AS IT
ON II.ITEM_ID = IT.PARENT_ITEM_ID
INNER JOIN ITEM_INFO AS II2
ON II2.ITEM_ID = IT.ITEM_ID
WHERE II.RARITY = 'RARE'
ORDER BY II2.ITEM_ID DESC

 

+ Recent posts