Re:제로부터 시작하는 갓생

[MySQL] 오랜 기간 보호한 동물(2)_Lv.3 본문

CodeKata/SQL

[MySQL] 오랜 기간 보호한 동물(2)_Lv.3

기븜 2025. 2. 11. 09:45
문제 URLhttps://school.programmers.co.kr/learn/courses/30/lessons/59411
 

프로그래머스

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

programmers.co.kr

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_IDANIMAL_TYPEDATETIMEINTAKE_CONDITIONNAMESEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_IDANIMAL_TYPEDATETIMENAMESEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다. ANIMAL_OUTS 테이블의 ANIMAL_ID는 ANIMAL_INS의 ANIMAL_ID의 외래 키입니다.

입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 기간이 긴 순으로 조회해야 합니다.

 

요구사항

animal_ins테이블과 animal_outs테이블을 animal_id로 JOIN

입양을 간 동물 아이디, 이름 조회 select

outs테이블 입양일datetime에서 ins테이블 보호시작일datetime을 뺀 일수 확인

-> 보호기간이 긴 순으로 내림차순 order by

보호기간이 가장 길었던 동물 2마리 limit

풀이방법
더보기
-- 방법1
SELECT ao.animal_id,
       ao.name
FROM animal_ins ai
LEFT JOIN animal_outs ao ON ai.animal_id = ao.animal_id
order by ao.datetime-ai.datetime DESC
limit 2

-- 방법2
SELECT ao.ANIMAL_ID, 
       ao.NAME
FROM ANIMAL_OUTS OUTS
JOIN ANIMAL_INS INS ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
ORDER BY DATEDIFF(OUTS.DATETIME, INS.DATETIME) DESC
LIMIT 2

 

배운점

Q. 왜 입양을 간 동물을 where절로 필터링 하지 않는지?

입양을 가지 않은 동물은 null값이 생길텐데 왜 관련 처리를 하지 않는지?

A.  null값,where절 inner join사용으로 후순위 밀려나면서 따로 지정필요없음

 

Q. 해당 문제를 inner join으로 풀었을때와 left join으로 풀었을때의 차이?

A. inner join: 두 테이블에 모두 존재하는 동물만 조회

left join:

왼쪽 조인은 왼쪽 테이블(ANIMAL_OUTS)의 모든 행을 반환하고

오른쪽 테이블(ANIMAL_INS)에서 일치하는 행이 있으면 그 값을 반환

ANIMAL_OUTS 테이블에 존재하는 모든 동물을 조회하고 ANIMAL_INS 테이블에 일치하는 기록이 없는 경우에도 포함

일치하지 않는 경우, 오른쪽 테이블의 열은 NULL 값을 가짐

이 경우 보호소에 들어온 기록이 없지만 입양된 동물도 포함될 수 있음

 

* DATEDIFF()

정의: 

SELECT DATEDIFF('구분자','Start_Date','End_Date')
  구분자 약어
년도 year yy & yyyy
분기 quarter q & qq
month m & mm
day d & dd
week wk
시간 hour m
minute n & mi
second s & ss