최종 아이템 찾기 (NOT IN, NULL 주의)

창하쿠·2025년 5월 22일

sql questions

목록 보기
3/7

게임 아이템 업그레이드 구조를 다루는 실전 예제를 통해 NOT IN 문법과, 그에 숨겨진 위험 요소인 NULL 이슈를 확실히 정리한다.


✅ 문제 배경

게임에는 아이템 업그레이드 트리가 존재한다. 아래는 업그레이드 관계의 예시다:

ITEM_A → ITEM_B → ITEM_D
         ↘ ITEM_C
  • ITEM_D, ITEM_C는 더 이상 업그레이드가 불가능한 아이템이다.
  • 이러한 최종 아이템들을 SQL로 조회하는 것이 목표다.

📦 테이블 구조

ITEM_INFO

ITEM_IDITEM_NAMERARITYPRICE
0ITEM_ARARE10000
1ITEM_BRARE9000
2ITEM_CLEGEND11000
3ITEM_DRARE10000
4ITEM_ERARE12000

ITEM_TREE

ITEM_IDPARENT_ITEM_ID
0NULL
10
20
31
41

✅ 최종 아이템 찾기 쿼리

SELECT
  ITEM_ID,
  ITEM_NAME,
  RARITY
FROM ITEM_INFO
WHERE ITEM_ID NOT IN (
  SELECT DISTINCT PARENT_ITEM_ID
  FROM ITEM_TREE
  WHERE PARENT_ITEM_ID IS NOT NULL
)
ORDER BY ITEM_ID DESC;

🔍 쿼리 설명

  • PARENT_ITEM_ID로 등장한 ITEM은 업그레이드 가능한 "부모 아이템"이다.
  • ITEM_ID NOT IN (...) 조건을 통해, 이 목록에 포함되지 않은 아이템만 걸러낸다.
  • 즉, 업그레이드 대상이 아닌 "최종 아이템"만 추려낼 수 있다.
  • IS NOT NULL 조건은 꼭 필요하다. 이유는 아래에서 설명한다.

⚠️ NOT IN과 NULL의 함정

NOT IN 서브쿼리 결과에 NULL이 하나라도 포함되면 전체 비교가 UNKNOWN이 되어버린다.

SELECT 1
WHERE 5 NOT IN (1, 2, NULL);  -- 결과 없음 (UNKNOWN)

SQL에서는 WHERE 조건이 TRUE일 때만 결과가 반환되며, UNKNOWN은 제외된다.

즉, NULL이 껴 있는 순간 NOT IN 조건은 절대 TRUE가 될 수 없으며, 모든 행이 필터된다.


✅ 해결책: NULL 제거

WHERE ITEM_ID NOT IN (
  SELECT PARENT_ITEM_ID
  FROM ITEM_TREE
  WHERE PARENT_ITEM_ID IS NOT NULL
)

IS NOT NULL 조건을 통해 NULL 값을 제거한 후 NOT IN을 사용해야 정확하게 동작한다.


📌 결론 정리

  • NOT IN은 간단한 문법처럼 보이지만, NULL 하나로 전부 무력화될 수 있다.
  • 서브쿼리에 NULL 가능성이 있다면 반드시 IS NOT NULL을 함께 사용해야 한다.
  • 실무에서도 흔히 발생하는 실수이므로 꼭 주의해야 한다.

✅ 실전 팁 요약

상황처리 방식
NOT IN + NULL 가능성 있음WHERE ... IS NOT NULL로 제거
IN만 사용할 때NULL 영향 없음
JOIN으로 우회 가능 여부경우에 따라 LEFT JOIN으로 가능

🔚 NOT IN은 작지만 위험한 문법이다.
NULL을 제대로 처리하지 않으면, 원하지 않는 결과가 나올 수 있다.
실전에서는 반드시 IS NOT NULL을 붙여서 안전하게 사용하는 습관을 들여야 한다. 💥

profile
아무것도 모르는 아무개

0개의 댓글