Algorithm/Programmers

[programmers lv.4] '보호소에서 중성화한 동물' MySQL 풀이

쉬지마 이굥진 2025. 4. 20. 23:50

문제

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블이 주어지고, 여기서 보호소에 들어왔을 땐 중성화 되지 않았지만 나갈 땐 중성화 된 동물들의 아이디와 타입, 이름을 아이디 순으로 오름차순 정렬해서 조회하면 되는 문제였음

 

1차 풀이 ➡️실패

SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS I
JOIN (
    SELECT ANIMAL_ID
    FROM ANIMAL_OUTS
    WHERE SEX_UPON_OUTCOME = 'Spayed' OR 'Neutered'
) J
ON I.ANIMAL_ID = J.ANIMAL_ID
WHERE SEX_UPON_INTAKE = 'Intact'
ORDER BY I.ANIMAL_ID
;

조회되는 데이터가 0건으로 아무것도 나오지 않았음

왜 이렇게 나오나 분석해보자.

 

원인 분석

이유인 즉 내가 문제를 대충 읽고 .. 

냅다 이 부분만 보고 조건절을 'Spayed' OR 'Neutered' 라고 줘 버림

 

문제의 부분 

WHERE SEX_UPON_OUTCOME = 'Spayed' OR 'Neutered'

다시 테이블 보니까 값이 다름 ㅋㅋ

 

조건절을 저렇게 짜 버리면 완전일치 비교가 돼서 Spayed Female이나 Spayed Male 같은 실제 데이터를 1도 찾아내지 못하게 댐 (다들 아시죠)

그래서 조인되는 서브쿼리에서 데이터가 0개가 되버려서 JOIN 할 게 없으니 전체 데이터도 0개가 되버리는 것

 

2차 풀이 ➡️실패

그래서 완전일치 비교를 할 수 있도록 컬럼값을 정확하게 입력해줌

SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS I
JOIN (
    SELECT ANIMAL_ID
    FROM ANIMAL_OUTS
    WHERE SEX_UPON_OUTCOME = 'Spayed Female' OR 'Neutered Male'
) J
ON I.ANIMAL_ID = J.ANIMAL_ID
WHERE SEX_UPON_INTAKE = 'Intact Male' OR 'Intact Female'
ORDER BY I.ANIMAL_ID
;

근데도 틀림 아놔

 

2차 원인 분석

또 조건절이 문제였음

WHERE SEX_UPON_OUTCOME = 'Spayed Female' OR 'Neutered Male'

 

SQL은 이 조건절을 아래와 같이 해석함

WHERE (SEX_UPON_OUTCOME = 'Spayed Female') OR ('Neutered Male')

 

여기서 문제는 'Neutered Male' 임

  • 'Neutered Male'는 비교 조건이 아니라 그냥 문자열 상수
  • SQL에서 문자열 상수는 WHERE 절에서 항상 TRUE로 평가되기도 함 (DBMS마다 다름).
  • 따라서 이 WHERE 조건은항상 참(TRUE)처럼 작동할 수 있고, 실제로는 SEX_UPON_OUTCOME = 'Spayed Female' 조건만 유효하게 되는 것

➡️결과적으로 SEX_UPON_OUTCOME = 'Spayed Female'에만 해당하는 동물만 필터링되고, 'Neutered Male'은 조건식이 아니라 무시되거나 잘못 작동하게 됨

 

메인쿼리의 조건절도 마찬가지! 두개 다 조건절을 고쳐보자

 

3차 풀이 ➡️ 성공 ⭕

SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS I
JOIN (
    SELECT ANIMAL_ID
    FROM ANIMAL_OUTS
    WHERE SEX_UPON_OUTCOME = 'Spayed Female' OR SEX_UPON_OUTCOME = 'Neutered Male'
) J
ON I.ANIMAL_ID = J.ANIMAL_ID
WHERE SEX_UPON_INTAKE = 'Intact Male' OR SEX_UPON_INTAKE = 'Intact Female'
ORDER BY I.ANIMAL_ID
;

 

야무지게 잘 뱉어냄

 

여기서 더 깔끔하게 할 수도 있음

 

최종 코드 💫

문자열 패턴 비교에 유용한 LIKE 연산자를 사용하면 매칭을 더 쉽게 할 수 있음

SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS I
JOIN (
    SELECT ANIMAL_ID
    FROM ANIMAL_OUTS
    WHERE SEX_UPON_OUTCOME LIKE 'Spayed%' or SEX_UPON_OUTCOME LIKE 'Neutered%'
) J
ON I.ANIMAL_ID = J.ANIMAL_ID
WHERE SEX_UPON_INTAKE LIKE 'Intact%'
ORDER BY I.ANIMAL_ID
;

결론

  • 조건이 2개 이상일 때는 각 조건마다 컬럼명을 반복해서 명시해야 함
  • 예를 들어 A = x OR A = y처럼 써야 하고, A = x OR y는 잘못된 문법임을 명심할 것
  • 문자열 비교할 땐 LIKE 연산자 쓰자. (자꾸 까먹는다ㅠ)

 

오늘도 땡큐포와칭 ~