본문 바로가기
Algorithm/Programmers SQL

[MySQL] 프로그래머스 오랜 기간 보호한 동물(1)

by 제우제우 2024. 9. 16.

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

코딩테스트 연습 > JOIN > 오랜 기간 보호한 동물(1)

문제 분석

난이도: LEVEL3

 

문제 요구사항

아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다.

정답 코드1

WITH CTE AS (
    SELECT ANIMAL_ID
    FROM ANIMAL_OUTS
)
SELECT NAME, DATETIME
FROM ANIMAL_INS 
WHERE ANIMAL_ID NOT IN (SELECT * FROM CTE)
ORDER BY DATETIME 
LIMIT 3

 

처음에 매번 입양을 간 아이디를 ANIMAL_OUT에서 구하기 힘드니까 CTE를 적용해야지 했는데

생각해 보니까 이렇게 하면 CTE를 만든 의미가 없다는 생각이 들었다. 

 

정답 코드2

SELECT NAME, DATETIME
FROM ANIMAL_INS 
WHERE ANIMAL_ID NOT IN (SELECT ANIMAL_ID FROM ANIMAL_OUTS)
ORDER BY DATETIME 
LIMIT 3

 

정답 코드1 → 의미 없는 CTE 제거 

 

정답 코드3

SELECT I.NAME, I.DATETIME
FROM ANIMAL_INS I LEFT JOIN ANIMAL_OUTS O
ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE O.ANIMAL_ID IS NULL 
ORDER BY 2
LIMIT 3

 

정답 코드2는 매번 WHERE 절에서 ANIMAL_OUTS에 대한 서브 쿼리가 실행된다. N+1 문제

그래서 ANIMAL_INS 테이블을 기준으로 LEFT JOIN 하고 ON 절에 ON I.ANIMAL_ID = O.ANIMAL_ID 주어서 

입양을 간 ID는 O.ANIMAL_ID 가 NULL이 아닌 값이 있을테니 

WHERE 절에 O.ANIMAL_ID IS NULL 조건을 준다.