오랜 기간 보호한 동물(1)
JOIN
오랜 기간 보호한 동물(1)
문제 설명
다음은 동물 보호소에서 관리하는 정보를 담은 ANIMAL_INS 테이블과 동물 보호소에서 입양 보낸 동물의 정보를 담은 ANIMAL_OUTS 테이블입니다.
ANIMAL_INS 테이블
Column name | Type | Nullable | Description |
---|---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE | 동물 ID |
ANIMAL_TYPE | VARCHAR(N) | FALSE | 생물 종 |
DATETIME | DATETIME | FALSE | 보호 시작일 |
INTAKE_CONDITION | VARCHAR(N) | FALSE | 보호 시작 시 상태 |
NAME | VARCHAR(N) | TRUE | 이름 |
SEX_UPON_INTAKE | VARCHAR(N) | FALSE | 성별 및 중성화 여부 |
ANIMAL_OUTS 테이블
Column name | Type | Nullable | Description |
---|---|---|---|
ANIMAL_ID | VARCHAR(N) | FALSE | 동물 ID |
ANIMAL_TYPE | VARCHAR(N) | FALSE | 생물 종 |
DATETIME | DATETIME | FALSE | 입양일 |
NAME | VARCHAR(N) | TRUE | 이름 |
SEX_UPON_OUTCOME | VARCHAR(N) | FALSE | 성별 및 중성화 여부 |
ANIMAL_OUTS 테이블의 ANIMAL_ID
는 ANIMAL_INS의 ANIMAL_ID
의 외래 키입니다.
문제
아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다. ※ 입양을 가지 못한 동물이 3마리 이상인 경우만 입력으로 주어집니다.
풀이 과정
- 조건 확인
- 입양되지 못한 동물만 찾기 위해 ANIMAL_OUTS 테이블에 해당 동물의 기록이 없는 경우를 필터링해야 함
- 테이블 결합 (LEFT JOIN)
- 두 테이블을
ANIMAL_ID
기준으로 결합 - LEFT JOIN 선택 이유: 모든 보호소에 들어온 동물을 기준으로 하고, 입양되지 않은 동물을 포함하기 위해 사용
- 두 테이블을
- 조건 필터링
- WHERE AO.
ANIMAL_ID
IS NULL 조건을 사용하여 입양 기록이 없는 동물만 선택 - LEFT JOIN 결과에서 입양 기록이 없는 경우, ANIMAL_OUTS 테이블의
ANIMAL_ID
는 NULL로 반환되므로 이를 활용한 것
- WHERE AO.
- 결과 정렬
- 정렬 기준에 따라 ORDER BY로 결과 정렬
- 보호 시작일을 기준으로 오름차순 정렬해야 하므로 ORDER BY AI.
DATETIME
ASC 사용
- 보호 시작일을 기준으로 오름차순 정렬해야 하므로 ORDER BY AI.
- 정렬 기준에 따라 ORDER BY로 결과 정렬
- 상위 3마리로 제한
- FETCH FIRST 3 ROWS ONLY를 사용하여 상위 3마리만 출력
- 최종 결과 출력
- SELECT 절에서 이름(
NAME
)과 입양일(DATETIME
) 출력
- SELECT 절에서 이름(
- 교훈
- 나는 오라클 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
- 입양되지 못한 동물 조회
LEFT JOIN
: ANIMAL_INS 테이블의 모든 동물을 기준으로 하되, 입양된 기록이 없는 동물만 걸러내기 위해 사용- WHERE AO.
ANIMAL_ID
IS NULL: ANIMAL_OUTS 테이블에 기록이 없는 동물(ANIMAL_ID
)만 선택하여 입양되지 않은 동물을 필터링- 상위 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;
Useful link
This post is licensed under Park Juyoung by the author.