문제
https://school.programmers.co.kr/learn/courses/30/lessons/273712
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
❌ 처음 작성한 쿼리
SELECT item_id, item_name, rarity
FROM item_info
WHERE item_id NOT IN (
SELECT DISTINCT parent_item_id
FROM item_tree
)
order by item_id desc
;
- 이 쿼리에서 parent_item_id를 SELECT했는데, NULL 값이 포함될 수 있음
- parent_item_id는 ROOT 아이템에 대해 NULL 값을 가지니까, 결국 NULL이 포함된 결과가 NOT IN 서브쿼리 안에 들어가게 됨
NULL 값이 포함되면 NOT IN이 문제가 되는 이유
NOT IN을 사용할 때, 비교 대상 리스트에 NULL 값이 하나라도 포함되면, SQL의 삼항 논리(boolean logic) 에 의해 비교 결과가 UNKNOWN이 돼서 항상 FALSE로 처리됨
WHERE item_id NOT IN (NULL, 0, 1, 2)
이러면 item_id = 3 같은 값을 비교할 때
3 NOT IN (NULL, 0, 1, 2) → UNKNOWN (즉, FALSE 취급)
그래서 모든 비교가 FALSE가 되어 원하는 결과를 얻지 못하는 문제가 발생!
IS NOT NULL을 추가하자!
방법 1: WHERE parent_item_id IS NOT NULL 추가
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
;
방법 2: NOT EXISTS 사용
SELECT i.item_id, i.item_name, i.rarity
FROM item_info i
WHERE NOT EXISTS (
SELECT 1
FROM item_tree t
WHERE t.parent_item_id = i.item_id
)
order by item_id desc
;
- NOT EXISTS는 값을 직접 비교하는 게 아니라, 서브쿼리의 결과 존재 여부만 판단하기 때문에 NULL 문제를 피할 수 있음
- 즉, item_info에 있는 item_id가 parent_item_id로 존재하지 않는 경우만 선택됨
결론
- NOT IN을 사용할 때 서브쿼리 결과에 NULL이 포함되면 의도한 결과가 나오지 않을 수 있음
- 해결책
- WHERE parent_item_id IS NOT NULL을 추가해서 NULL을 제거
- NOT EXISTS를 사용하면 더 안전하게 해결 가능
'문제 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 / Java] 유연근무제 (0) | 2025.03.06 |
---|---|
[프로그래머스 / Java] 지게차와 크레인 (0) | 2025.03.03 |
[프로그래머스] 자동차 대여 기록에서 장기/단기 대여 구분하기 - MySQL (0) | 2025.01.25 |
[프로그래머스] 잡은 물고기 중 가장 큰 물고기의 길이 구하기 - MySQL (1) | 2025.01.25 |
[프로그래머스] Python 개발자 찾기 - MySQL (0) | 2025.01.25 |