2025. 4. 5. 16:35ㆍTools & Skills/SQL
문제 설명


보호소에서 중성화 수술을 거친 동물 정보를 알아보려 합니다.
보호소에 들어올 당시에는 중성화되지 않았지만, 보호소를 나갈 당시에는 중성화된
동물의 아이디와 생물 종, 이름을 조회하는 아이디 순으로 조회하는 SQL 문을 작성해주세요.
처음 작성한 풀이
- 보호소에 들어올 당시 중성화 x → ANIMAL_INS 테이블과
- 보호소를 나갈 당시 중성화 o → ANIMAL_OUTS 테이블을 JOIN
- 동물 아이디와 생물 종, 이름을 조회
- 아이디 순 정렬 → ORDER BY
SELECT A.ANIMAL_ID, A.ANIMAL_TYPE, A.NAME
FROM ANIMAL_INS A
JOIN ANIMAL_OUTS B ON (B.ANIMAL_ID = A.ANIMAL_ID)
WHERE A.SEX_UPON_INTAKE LIKE 'Intact%'
AND B.SEX_UPON_OUTCOME LIKE 'Spayed%' OR B.SEX_UPON_OUTCOME LIKE 'Neutered%'
ORDER BY ANIMAL_ID;
왜 틀렸을까?
오답 분석
WHERE 절의 논리 오류
WHERE A.SEX_UPON_INTAKE LIKE 'Intact%'
AND B.SEX_UPON_OUTCOME LIKE 'Spayed%' OR B.SEX_UPON_OUTCOME LIKE 'Neutered%'
OR 연산자의 우선순위가 낮기 때문에 AND 조건보다 먼저 적용되지 않음
→ 결과적으로 B.SEX_UPON_OUTCOME LIKE ‘Neutered%’ 조건이 전체 WHERE 절과 독립적으로 적용됨
→ 올바른 논리는 OR 조건을 ( )로 묶어야 함
💡 수정된 풀이
SELECT A.ANIMAL_ID, A.ANIMAL_TYPE, A.NAME, A.SEX_UPON_INTAKE
FROM ANIMAL_INS A
JOIN ANIMAL_OUTS B ON B.ANIMAL_ID = A.ANIMAL_ID
WHERE A.SEX_UPON_INTAKE LIKE 'Intact%'
AND (B.SEX_UPON_OUTCOME LIKE 'Spayed%' OR B.SEX_UPON_OUTCOME LIKE 'Neutered%')
ORDER BY A.ANIMAL_ID;
다른 풀이는 없을까?
1. CASE WHEN을 활용한 방법
SELECT A.ANIMAL_ID, A.ANIMAL_TYPE, A.NAME
FROM ANIMAL_INS A
JOIN ANIMAL_OUTS B ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE CASE
WHEN A.SEX_UPON_INTAKE LIKE 'Intact%'
AND (B.SEX_UPON_OUTCOME LIKE 'Spayed%' OR B.SEX_UPON_OUTCOME LIKE 'Neutered%')
THEN 1 ELSE 0 END = 1
ORDER BY A.ANIMAL_ID;
🔍 특징
CASE WHEN을 활용하여 조건을 보다 명확하게 설정할 수 있고,
WHERE 절이 직관적이지 않다면, 논리 조건을 가독성 좋게 분리 가능하다.
즉, WHERE 조건이 복잡할 때 사용하면 가독성 증가
2. EXISTS 서브쿼리 활용한 방법
SELECT ANIMAL_ID, ANIMAL_TYPE, NAME
FROM ANIMAL_INS A
WHERE SEX_UPON_INTAKE LIKE 'Intact%'
AND EXISTS (
SELECT 1
FROM ANIMAL_OUTS B
WHERE A.ANIMAL_ID = B.ANIMAL_ID
AND (B.SEX_UPON_OUTCOME LIKE 'Spayed%' OR B.SEX_UPON_OUTCOME LIKE '%Neutered%')
)
ORDER BY ANIMAL_ID;
🔍 특징
EXISTS를 사용하여 ANIMAL_OUTS 테이블에서 중성화된 동물만 존재하는 경우 필터링할 수 있고,
큰 데이터셋에서는 JOIN보다 빠를 수 있다. (EXISTS는 조건 만족 시 즉시 중단)
→ ANIMAL_OUTS에 중복 데이터가 많거나 JOIN의 성능 이슈가 발생하는 경우
3가지 풀이의 차이는?
방법 | 특징 | 성능(속도) | 사용 추천 |
JOIN + WHERE | 가장 기본적인 방법, 직관적 | 빠름 | 기본적인 집계 문제 |
CASE WHEN | 가독성 높지만 성능 저하 가능 | 상대적으로 느림 | 복잡한 논리 조건이 있을 때 |
EXISTS 서브쿼리 | JOIN 없이도 조건 만족하는 데이터만 조회 | 빠름 (특정 상황에서) | JOIN이 비효율적일 때 |
✅ 가장 효율적인 해결 방법은 JOIN + WHERE 방식
WHY? SQL 엔진에서 JOIN 최적화가 잘 동작하므로 기본적으로 접근하자.
→ EXISTS는 JOIN보다 효율적일 수 있으나, 데이터셋 크기에 따라 비효율적일 수 있다.
결론
결론적으로 1차 정답 풀이(JOIN 사용)가 최적의 해결 방법!
'Tools & Skills > SQL' 카테고리의 다른 글
[SQL] LeetCode #511 - Game Play Analysis (0) | 2025.03.19 |
---|---|
정규화 (0) | 2025.03.19 |
서브쿼리(Subquery) (0) | 2025.03.05 |
RDBMS (1) | 2025.02.06 |