본문 바로가기

SQL/SQL 코딩테스트

[mysql] 업그레이드 할 수 없는 아이템 구하기

728x90

문제 설명

어느 한 게임에서 사용되는 아이템들은 업그레이드가 가능합니다.

'ITEM_A'->'ITEM_B'와 같이 업그레이드가 가능할 때

'ITEM_A'를 'ITEM_B'의 PARENT 아이템,

PARENT 아이템이 없는 아이템을 ROOT 아이템이라고 합니다.

예를 들어 'ITEM_A'->'ITEM_B'->'ITEM_C' 와 같이 업그레이드가 가능한 아이템이 있다면

'ITEM_C'의 PARENT 아이템은 'ITEM_B'

'ITEM_B'의 PARENT 아이템은 'ITEM_A'

ROOT 아이템은 'ITEM_A'가 됩니다.

다음은 해당 게임에서 사용되는 아이템 정보를 담은 ITEM_INFO 테이블과 아이템 관계를 나타낸 ITEM_TREE 테이블입니다.

ITEM_INFO 테이블은 다음과 같으며, ITEM_ID, ITEM_NAME, RARITY, PRICE는 각각 아이템 ID, 아이템 명, 아이템의 희귀도, 아이템의 가격을 나타냅니다.

Column name Type Nullable

ITEM_ID INTEGER FALSE
ITEM_NAME VARCHAR(N) FALSE
RARITY INTEGER FALSE
PRICE INTEGER FALSE

ITEM_TREE 테이블은 다음과 같으며, ITEM_ID, PARENT_ITEM_ID는 각각 아이템 ID, PARENT 아이템의 ID를 나타냅니다.

Column name Type Nullable

ITEM_ID INTEGER FALSE
PARENT_ITEM_ID INTEGER TRUE

단, 각 아이템들은 오직 하나의 PARENT 아이템 ID 를 가지며, ROOT 아이템의 PARENT 아이템 ID 는 NULL 입니다.

ROOT 아이템이 없는 경우는 존재하지 않습니다.


문제

더 이상 업그레이드할 수 없는 아이템의 아이템 ID(ITEM_ID), 아이템 명(ITEM_NAME), 아이템의 희귀도(RARITY)를 출력하는 SQL 문을 작성해 주세요. 이때 결과는 아이템 ID를 기준으로 내림차순 정렬해 주세요.


예시

예를 들어 ITEM_INFO 테이블이 다음과 같고

ITEM_ID ITEM_NAME RARITY PRICE

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

ITEM_TREE 테이블이 다음과 같다면

ITEM_ID PARENT_ITEM_ID

0 NULL
1 0
2 0
3 1
4 1

'ITEM_A' 는 'ITEM_B', 'ITEM_C' 로 업그레이드가 가능하며 'ITEM_B' 는 'ITEM_D', 'ITEM_E' 로 업그레이드가 가능합니다. 'ITEM_C', 'ITEM_D', 'ITEM_E' 는 더 이상 업그레이드가 가능하지 않으므로 결과는 다음과 같이 나와야 합니다.

ITEM_ID ITEM_NAME RARITY

4 ITEM_E RARE
3 ITEM_D RARE
2 ITEM_C LEGEND

 

select item_id, item_name, rarity
from item_info
where NOT EXISTS(
    select parent_item_id
from item_tree
where item_info.item_id = item_tree.parent_item_id
)
order by item_id desc

 

처음에는 not in을 쓸려고 했는데 실패

-> 이유는 not in 은 null 값이 있으면 안됨

 

✅ 왜 NOT IN은 NULL이 있으면 안 되는가?

SQL에서는 NOT IN (값 목록)에서 값 목록에 NULL이 하나라도 포함되면
비교 자체가 "모호(UNKNOWN)"해져서 결과를 모두 제외해버려.

예를 들어:

 
WHERE item_id NOT IN (1001, 1002, NULL)

이건 내부적으로는 이런 의미야:

 
WHERE item_id ≠ 1001 AND item_id ≠ 1002 AND item_id ≠ NULL ← 이건 판단할 수 없어서 전체 조건이 UNKNOWN 처리됨!

SQL에서 조건이 UNKNOWN이면 FALSE로 간주돼서 해당 행은 제외돼버려.


✅ 반면에 NOT EXISTS는 왜 되냐?

NOT EXISTS는 단순히:

"이 조건에 맞는 행이 존재하지 않으면 TRUE"

라는 존재 여부만 판단하기 때문에,
NULL이 있든 말든 상관없이 동작해.

sql
복사편집
WHERE NOT EXISTS ( SELECT 1 FROM item_tree WHERE item_info.item_id = item_tree.parent_item_id )

이건 단순히:

  • item_info.item_id랑 매칭되는 item_tree.parent_item_id가 있냐?
  • 없으면 출력해.

→ NULL이 있든 없든, 매칭 안 되면 결과에 포함돼.

 

만약 not in을 쓰고싶다면

select item_id, item_name, rarity
from item_info
where item_info.item_id not in(
    select parent_item_id
from item_tree
where item_id is not null
)
order by item_id desc

 

하면 될듯

728x90