Post

오랜 기간 보호한 동물(1)

JOIN

오랜 기간 보호한 동물(1)


문제 설명

다음은 동물 보호소에서 관리하는 정보를 담은 ANIMAL_INS 테이블과 동물 보호소에서 입양 보낸 동물의 정보를 담은 ANIMAL_OUTS 테이블입니다.


ANIMAL_INS 테이블

Column nameTypeNullableDescription
ANIMAL_IDVARCHAR(N)FALSE동물 ID
ANIMAL_TYPEVARCHAR(N)FALSE생물 종
DATETIMEDATETIMEFALSE보호 시작일
INTAKE_CONDITIONVARCHAR(N)FALSE보호 시작 시 상태
NAMEVARCHAR(N)TRUE이름
SEX_UPON_INTAKEVARCHAR(N)FALSE성별 및 중성화 여부


ANIMAL_OUTS 테이블

Column nameTypeNullableDescription
ANIMAL_IDVARCHAR(N)FALSE동물 ID
ANIMAL_TYPEVARCHAR(N)FALSE생물 종
DATETIMEDATETIMEFALSE입양일
NAMEVARCHAR(N)TRUE이름
SEX_UPON_OUTCOMEVARCHAR(N)FALSE성별 및 중성화 여부

ANIMAL_OUTS 테이블의 ANIMAL_ID는 ANIMAL_INS의 ANIMAL_ID의 외래 키입니다.




문제

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




풀이 과정
  1. 조건 확인
    • 입양되지 못한 동물만 찾기 위해 ANIMAL_OUTS 테이블에 해당 동물의 기록이 없는 경우를 필터링해야 함
  2. 테이블 결합 (LEFT JOIN)
    • 두 테이블을 ANIMAL_ID 기준으로 결합
    • LEFT JOIN 선택 이유: 모든 보호소에 들어온 동물을 기준으로 하고, 입양되지 않은 동물을 포함하기 위해 사용
  3. 조건 필터링
    • WHERE AO.ANIMAL_ID IS NULL 조건을 사용하여 입양 기록이 없는 동물만 선택
    • LEFT JOIN 결과에서 입양 기록이 없는 경우, ANIMAL_OUTS 테이블ANIMAL_ID는 NULL로 반환되므로 이를 활용한 것
  4. 결과 정렬
    • 정렬 기준에 따라 ORDER BY로 결과 정렬
      • 보호 시작일을 기준으로 오름차순 정렬해야 하므로 ORDER BY AI.DATETIME ASC 사용
  5. 상위 3마리로 제한
    • FETCH FIRST 3 ROWS ONLY를 사용하여 상위 3마리만 출력
  6. 최종 결과 출력
    • SELECT 절에서 이름(NAME)입양일(DATETIME) 출력
  • 교훈
    • 나는 오라클 12 버전 밑에서 프로젝트를 진행했어서 ROWNUM에 익숙했는데…. FETCH FIRST 숫자 ROWS ONLY 요거 외우자. 잘 써보자.




정답

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 
    AI.NAME, 
    AI.DATETIME
FROM 
    ANIMAL_INS AI
LEFT JOIN 
    ANIMAL_OUTS AO
ON 
    AI.ANIMAL_ID = AO.ANIMAL_ID
WHERE 
    AO.ANIMAL_ID IS NULL
ORDER BY 
    AI.DATETIME ASC
FETCH FIRST 3 ROWS ONLY;


Tip

  1. 입양되지 못한 동물 조회
    • LEFT JOIN: ANIMAL_INS 테이블의 모든 동물을 기준으로 하되, 입양된 기록이 없는 동물만 걸러내기 위해 사용
    • WHERE AO.ANIMAL_ID IS NULL: ANIMAL_OUTS 테이블에 기록이 없는 동물(ANIMAL_ID)만 선택하여 입양되지 않은 동물을 필터링
  2. 상위 3마리로 제한합니다.
    • FETCH FIRST 3 ROWS ONLY: 보호소에 가장 오래 있었던 동물 중 상위 3마리만 결과로 반환. (MYSQL로는 LIMIT 3;)

SQL Dialect Used: Oracle




개념 확인

  • LEFT JOIN
    • 기준 테이블의 모든 행을 유지하며, 일치하지 않는 경우에도 결과에 포함. 일치하지 않으면 NULL 반환
  • FETCH FIRST n ROWS ONLY
    • 결과에서 상위 n개의 행만 가져오는 절
    • Oracle 12c 이상에서는 이 구문을 사용하며, Oracle 11g 이하에서는 ROWNUM <= 3로 대체할 수 있음
    • MYSQL에서는 LIMIT n;




오랜 기간 보호한 동물(1)

This post is licensed under Park Juyoung by the author.

Trending Tags