문제
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 연산자 쓰자. (자꾸 까먹는다ㅠ)
오늘도 땡큐포와칭 ~
'Algorithm > Programmers' 카테고리의 다른 글
[programmers lv.2 python] '석유 시추' 파이썬 풀이 (이제 시간초과를 곁들인 ..) (3) | 2024.12.13 |
---|---|
[programmers lv1.python] 달리기 경주 풀이 (시간초과 해결) (0) | 2024.11.05 |
[programmers lv.1 python] '로또의 최저 순위와 최고 순위' 풀이 (2) | 2024.09.28 |
[programmers lv.1 python] 없는 숫자 더하기 (0) | 2024.08.12 |
[programmers lv.1 python] 서울에서 김서방 찾기 (초..간단하게 풀기) (4) | 2024.08.08 |