KDT 실무형 스프링 백엔드 엔지니어 양성과정 6기 | SQL CODEKATA
🦊 오랜 기간 보호한 동물(2)
🏷 관련 주제 : JOIN ORDER BY``SUBQUERY``ROWNUM
문제 설명
ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다.
ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.
| NAME | TYPE | NULLABLE |
|---|---|---|
| ANIMAL_ID | VARCHAR(N) | FALSE |
| 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 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다.
ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다.
ANIMAL_OUTS 테이블의 ANIMAL_ID는 ANIMAL_INS의 ANIMAL_ID의 외래 키입니다.
| NAME | TYPE | NULLABLE |
|---|---|---|
| ANIMAL_ID | VARCHAR(N) | FALSE |
| ANIMAL_TYPE | VARCHAR(N) | FALSE |
| DATETIME | DATETIME | FALSE |
| NAME | VARCHAR(N) | TRUE |
| SEX_UPON_OUTCOME | VARCHAR(N) | FALSE |
입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 조회하는 SQL문을 작성해주세요.
이때 결과는 보호 기간이 긴 순으로 조회해야 합니다.
예시
예를 들어, ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블이 다음과 같다면
ANIMAL_INS
| ANIMAL_ID | ANIMAL_TYPE | DATETIME | INTAKE_CONDITION | NAME | SEX_UPON_INTAKE |
|---|---|---|---|---|---|
| A354597 | Cat | 2014-05-02 12:16:00 | Normal | Ariel | Spayed Female |
| A362707 | Dog | 2016-01-27 12:27:00 | Sick | Girly Girl | Spayed Female |
| A370507 | Cat | 2014-10-27 14:43:00 | Normal | Emily | Spayed Female |
| A414513 | Dog | 2016-06-07 09:17:00 | Normal | Rocky | Neutered Male |
ANIMAL_OUTS
| ANIMAL_ID | ANIMAL_TYPE | DATETIME | NAME | SEX_UPON_OUTCOME |
|---|---|---|---|---|
| A354597 | Cat | 2014-06-03 12:30:00 | Ariel | Spayed Female |
| A362707 | Dog | 2017-01-10 10:44:00 | Girly Girl | Spayed Female |
| A370507 | Cat | 2015-08-15 09:24:00 | Emily | Spayed Female |
SQL문을 실행하면 다음과 같이 나와야 합니다.
| ANIMAL_ID | NAME |
|---|---|
| A362707 | Girly Girl |
| A370507 | Emily |
※ 입양을 간 동물이 2마리 이상인 경우만 입력으로 주어집니다.
본 문제는 Kaggle의 "Austin Animal Center Shelter Intakes and Outcomes"에서 제공하는 데이터를 사용하였으며 ODbL의 적용을 받습니다.
✔ Solution with SUBQUERY & JOIN & ROWNUM
SELECT *
FROM (SELECT I.ANIMAL_ID
, I.NAME
FROM ANIMAL_INS I
, ANIMAL_OUTS O
WHERE I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY O.DATETIME - I.DATETIME DESC)
WHERE ROWNUM <= 2;
실행 결과

💥 오늘 만난 문제 & 나의 시도 💦 & 해결 방법 👍
📌 오늘 만난 문제 : 입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디 이름을 조회하시오.
이 때, 결과는 보호 기간이 긴 순으로 조회합니다.
1. ANIAML_INS와 ANIMAL_OUTS를 ANIMAL_ID 칼럼을 기준으로 조인해서 조회하기
SELECT *
FROM ANIMAL_INS I
, ANIMAL_OUTS O
WHERE I.ANIMAL_ID = O.ANIMAL_ID;
실행 결과

2. 보호기간(ANIMAL_OUTS.DATETIME - ANIAML_INS.DATETIME)이 긴 순서대로 정렬해서 동물의 아이디와 이름 조회하기
SELECT I.ANIMAL_ID
, I.NAME
FROM ANIMAL_INS I
, ANIMAL_OUTS O
WHERE I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY O.DATETIME - I.DATETIME DESC;
실행 결과

3. 위에서 조회한 데이터 중 제일 첫 두 인스턴스만 조회하기
위의 코드를 FROM절의 서브쿼리로 주고 ROWNUM <= 2 조건을 WHERE절에 준다.
SELECT I.ANIMAL_ID
, I.NAME
FROM ANIMAL_INS I
, ANIMAL_OUTS O
WHERE I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY O.DATETIME - I.DATETIME DESC
실행 결과

처음에 보호 기간이 가장 긴 동물만을 조회하는 문제로 잘못 인지해서
보호기간이 가장 긴 동물을 조회했는데 인스턴스가 1개만 출력이 되었다. .😲⁉️
혹시 예시의 조회결과가 틀린 것인가?🤔❓라는 생각도 들어서
코드를 제출해 보기도 했지만 계속 틀렸다고 나오는 바람에 좀 짜증이 났다. 😤💢
하지만 그간의 경험으로 이런 경우는 보통
"내가 문제를 잘못 읽었을 때 🧐 "라는 것을 잘 알고 있었기 때문에
다시 문제를 읽어보았다.👁️👁️✨
아니나 다를까 보호 기간이 가장 긴 동물 두마리를 조회하라는 말의 의미가 🔎 🐶🐱
보호기간이 가장 긴 동물이 같은 기간으로 2마리가 조회된다는 의미가 아니라
보호기간이 가장 긴 순으로 정렬했을 때,
보호기간이 가장 긴 동물 2마리를 조회하라라는 의미였다.😅💘
아직은 SQL 코드카타의 문제 난이도가 높지 않아서
빨리 해결하려는 마음 때문에 문제 풀이에 실수가 많이 나오는 것 같다.
조금 더 집중해서 진지하게 문제를 풀 수 있도록 해야겠다.🤓
🎉 SQL CODEKATA CLEAR!🎉
💬 무엇을 새롭게 알았는지
- 조금 더 진지하게 집중해서 한번에 문제를 제대로 풀자!
- 문제를 잘 읽자!
- SQL QUERY 작성 연습
- SUBQUERY
- ORDER BY
- ROWNUM