프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지
문제 설명
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의 적용을 받습니다.
♥ 오라클 정답
select d.animal_id, d.name
from(select o.animal_id, o.name, (o.datetime - i.datetime) protect_time
from animal_ins i, animal_outs o
where i.animal_id = o.animal_id) d
order by protect_time desc fetch first 2 rows only;
♥ MySQL 정답
select d.animal_id, d.name
from(select o.animal_id, o.name, datediff(o.datetime, i.datetime) protect_time
from animal_ins i, animal_outs o
where i.animal_id = o.animal_id) d
order by protect_time desc limit 2;
해설해보기
이 문제는 EQUI JOIN 과 인라인뷰(from절의 서브쿼리)를 사용해서 풀 수 있다.
■ 인라인뷰
in line view의 select절에 필요한 컬럼들을 기입해준다.
이때 입양 간 동물의 보호기간은
animal_outs 테이블의 datetime에서 animal_ins의 datetime의 차로 구할 수 있다.
따라서 두 테이블을 EQUI JOIN 하여
서로 연결된 컬럼인 ANIMAL_IDF로 연결해준다.
단, 오라클에서는 마이너스 기호로 date의 차를 구할 수 있지만,
MySQL 에서는 datediff() 함수를 사용해서 차를 구해줘야한다.
▶ DATEDIFF( A, B )
DATE TYPE의 DATA FORMAT을 가진
값에 대하여 A-B를 구하는 함수이다.
■ 메인쿼리
메인쿼리의 SELECT절에 출력해야할 컬럼명을 입력해주는데,
FROM절에서 가져온 animal_id와 name을 기입해준다.
메인쿼리에서 중요한 것은
order by 절에 있다.
문제의 조건이 입양을 간 동물 중 보호 기간이 가장 길었던 동물 2마리에 대해서만 조회하는 것이다.
이 조건을 order by절에서 충족시켜줄 수 있다.
- -오라클의 경우
order by protect_time desc 로 우선 정렬조건을 준 후
정렬된 것을 기준으로 fetch first 2 rows only;를 사용해준다.
▶ desc fetch first 2 rows only
desc하게 정렬된 것을 기준으로 맨 위에서 (처음부터)
오직 2개의 행만 출력한다는 의미이다.
--MySQL의 경우
order by protect_time desc 로 우성 정렬조건을 준 후
정렬된 것을 기준으로 limit 2; 를 사용해준다.
▶ desc limit2
desc 하게 정렬된 것을 기준으로 2개만 출력하는 것으로 제한하는 것이다.
결과 출력
출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
'SQL 문제 풀기 > 1. 프로그래머스 SQL : 2023.12.17~2024.2.29' 카테고리의 다른 글
<프로그래머스 54>대여 기록이 존재하는 자동차 리스트 구하기(Lv.3) (2) | 2024.02.08 |
---|---|
<프로그래머스 53> 조건에 맞는 사용자와 총 거래금액 조회하기(Lv.3) (4) | 2024.02.07 |
<프로그래머스 51> 조건별로 분류하여 주문상태 출력하기(Lv.3) (2) | 2024.02.05 |
<프로그래머스 50> 있었는데요 없었습니다.(Lv.3) (0) | 2024.02.04 |
<프로그래머스 49> 오랜 기간 보호한 동물(1)(Lv.3) (2) | 2024.02.03 |