ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 활용해 아직 입양을 못 간 동물 중 보호 기간이 가장 긴 동물 3마리의 이름과 보호시작일을 보호시작일 순으로 조회하는 문제이다.
| 테이블 | 주요 컬럼 |
|---|---|
ANIMAL_INS | ANIMAL_ID, NAME, DATETIME(보호시작일) |
ANIMAL_OUTS | ANIMAL_ID, DATETIME(입양일) |
문제를 읽고 아래처럼 풀이 흐름을 정리하였다.
ANIMAL_INS에는 있는데 ANIMAL_OUTS에 없는 동물 찾기INNER JOIN을 생각했는데, INNER JOIN은 양쪽 테이블에 모두 있는 데이터만 가져오기 때문에 적합하지 않았다. 이 경우에는 LEFT JOIN을 써야 한다.LEFT JOIN은 왼쪽 테이블(ANIMAL_INS)에 있는 행은 무조건 다 가져오고, 오른쪽(ANIMAL_OUTS)에 없으면 NULL로 채운다.
LEFT JOIN 결과:
I.ANIMAL_ID | O.ANIMAL_ID
A001 | A001 ← OUTS에 있음 (입양됨)
A002 | NULL ← OUTS에 없음 (아직 보호중)
A004 | NULL ← OUTS에 없음 (아직 보호중)
O.ANIMAL_ID가 NULL인 행이 바로 아직 입양되지 않은 동물이다. 따라서 WHERE O.ANIMAL_ID IS NULL로 필터링하면 보호중인 동물만 걸러낼 수 있다.
구체적으로 정리한 풀이 흐름:
ANIMAL_INS I와 ANIMAL_OUTS O를 ANIMAL_ID 기준으로 LEFT JOINWHERE O.ANIMAL_ID IS NULL로 OUTS에 없는 동물(보호중) 필터ORDER BY I.DATETIME으로 보호시작일 오름차순 정렬LIMIT 3으로 상위 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 I.DATETIME
LIMIT 3
INNER JOIN과 LEFT JOIN의 차이를 확실하게 이해하자.
| JOIN 종류 | 가져오는 데이터 |
|---|---|
INNER JOIN | 양쪽 테이블에 모두 있는 데이터만 |
LEFT JOIN | 왼쪽 테이블에 있으면 무조건 가져오고, 오른쪽에 없으면 NULL |
"A 테이블에는 있는데 B 테이블에는 없는" 데이터를 찾을 때는 LEFT JOIN + WHERE B.컬럼 IS NULL 패턴을 사용한다.