Programmers: MySQL Lv. 3

김소정·2022년 8월 28일
0

Problem Solving (SQL)

목록 보기
3/6
post-thumbnail

#1~4

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다. ANIMAL_OUTS 테이블의 ANIMAL_IDANIMAL_INSANIMAL_ID의 외래 키입니다.


#1 없어진 기록 찾기

천재지변으로 인해 일부 데이터가 유실되었습니다. 입양을 간 기록은 있는데, 보호소에 들어온 기록이 없는 동물의 ID와 이름을 ID 순으로 조회하는 SQL문을 작성해주세요.

풀이

SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS AS OUTS
LEFT JOIN ANIMAL_INS AS INS
ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE INS.ANIMAL_ID IS NULL;

ANIMAL_OUTS에는 있지만, ANIMAL_INS에는 없는 동물을 찾아야 한다. 두 테이블을 모두 고려해야 하기 때문에, JOIN을 이용하여 두 테이블을 연결해주었다. ANIMAL_INS 테이블의 ANIMAL_IDNULL 값인, 즉 해당 테이블에서는 아이디가 없는 동물을 찾으라는 조건절을 정의해 주었다.


#2 있었는데요 없었습니다

관리자의 실수로 일부 동물의 입양일이 잘못 입력되었습니다. 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일이 빠른 순으로 조회해야합니다.

풀이

SELECT INS.ANIMAL_ID, INS.NAME
FROM ANIMAL_INS AS INS
LEFT JOIN ANIMAL_OUTS AS OUTS
ON INS.ANIMAL_ID = OUTS.ANIMAL_ID
WHERE OUTS.DATETIME < INS.DATETIME
ORDER BY INS.DATETIME;

두 테이블을 참조하기 위해서 테이블을 조인시켜준 뒤에, 문제에서 요구하는 입양일 < 시작일 조건을 주면 된다. 여기서 주의해야 할 점은 테이블의 별칭을 꼭 컬럼 앞에 붙여주어야 한다는 점이다.


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

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

풀이

SELECT A.NAME, A.DATETIME
FROM ANIMAL_INS A LEFT JOIN ANIMAL_OUTS B
ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE B.ANIMAL_ID IS NULL
ORDER BY A.DATETIME
LIMIT 3;
  1. 입양을 못 간 동물만을 확인하기 위해서는 ANIMAL_OUTS 테이블에 동물 아이디가 없는 동물들만을 추출하면 된다.
    : WHERE B.ANIMAL_ID IS NULL
  2. 보호 시작일 순으로 조회하기 위해서는 ORDER BY를 통해 정렬해준다.
  3. 조건을 충족하는 동물 중 3마리만 조회하기 위해서, LIMIT 조건을 준다.

#4 오랜 기간 보호한 동물 (2)

입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 기간이 긴 순으로 조회해야 합니다.

풀이

SELECT A.ANIMAL_ID, A.NAME
FROM ANIMAL_INS A, ANIMAL_OUTS B
WHERE A.ANIMAL_ID = B.ANIMAL_ID
ORDER BY B.DATETIME-A.DATETIME DESC
LIMIT 2;

보호 기간은 ANIMAL_OUTS 테이블의 DATETIME 컬럼과 ANIMAL_INS 테이블의 DATETIME 컬럼의 차로 구해준다. 해당 값을 역순으로 정렬하고 LIMIT를 이용해 2개의 값만 조회하면, 문제에서 요구한 보호 기간이 가장 긴 동물 두 마리의 정보를 확인할 수 있다.


#5

PLACES 테이블은 공간 임대 서비스에 등록된 공간의 정보를 담은 테이블입니다. PLACES 테이블의 구조는 다음과 같으며 ID, NAME, HOST_ID는 각각 공간의 아이디, 이름, 공간을 소유한 유저의 아이디를 나타냅니다. ID는 기본키입니다.

#5 헤비 유저가 소유한 장소

이 서비스에서는 공간을 둘 이상 등록한 사람을 "헤비 유저"라고 부릅니다. 헤비 유저가 등록한 공간의 정보를 아이디 순으로 조회하는 SQL문을 작성해주세요.

풀이

SELECT A.ID, A.NAME, A.HOST_ID
FROM PLACES A
INNER JOIN (SELECT * FROM PLACES GROUP BY HOST_ID HAVING COUNT(HOST_ID) >= 2) B
ON A.HOST_ID = B.HOST_ID
ORDER BY A.ID;

해당 문제는 서브 쿼리를 이용해야 하는 문제였다. 기존의 PLACES 테이블과 문제에서 말한 "공간을 둘 이상 등록한 사람"에 해당하는 쿼리를 작성하여 두 테이블을 조인하면 된다.

공간을 둘 이상 등록한 사람만을 확인하기 위해, 해당 테이블을 HOST_ID로 그룹화 해준 뒤, HOST_IDCOUNT가 둘 이상인 행들을 조회하는 서브 쿼리를 작성해주었다.


Reference

https://school.programmers.co.kr/learn/challenges

profile
Yonsei University, Applied Statistics

0개의 댓글