CodingSpace

[프로그래머스/SQL] 오랜 기간 보호한 동물(1) (feat. LEFT JOIN, LIMIT) 본문

프로그래머스/SQL 고득점 Kit

[프로그래머스/SQL] 오랜 기간 보호한 동물(1) (feat. LEFT JOIN, LIMIT)

개발자_조이킴 2022. 3. 11. 16:13

Problem. 오랜 기간 보호한 동물(1)


Link.

https://programmers.co.kr/learn/courses/30/lessons/59044

 

코딩테스트 연습 - 오랜 기간 보호한 동물(1)

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr


Description.

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다.

ANIMAL_INS 테이블 구조는 다음과 같습니다.

  • ANIMAL_ID: 동물의 아이디
  • ANIMAL_TYPE: 생물 종
  • DATETIME: 보호 시작일
  • INTAKE_CONDITION: 보호 시작 시 상태
  • NAME: 이름
  • SEX_UPON_INTAKE: 성별 및 중성화 여부

예) ANIMAL_INS 테이블

ANIMAL_OUTS 테이블은 동물 보호소에 입양을 보낸 동물의 정보를 담은 테이블입니다.

ANIMAL_OUTS 테이블 구조는 다음과 같습니다.

  • ANIMAL_ID: 동물의 아이디
  • ANIMAL_TYPE: 생물 종
  • DATETIME: 입양일
  • NAME: 이름
  • SEX_UPON_INTAKE: 성별 및 중성화 여부

예) ANIMAL_OUTS 테이블

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

※ 결과는 보호 시작일 순으로 정렬합니다.


Key Point. 

본 문제는 LEFT JOIN을 사용하여 ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 결합하여 해결했다.

먼저, ON 명령어로 양 테이블의 ANIMAL_ID 기준으로 결합하도록 조건을 설정했다. 

그 다음 WHERE 조건문으로 ANIMAL_OUTS 테이블의 ANIMAL_ID가 NULL 경우만 조회하도록 쿼리문을 작성했다.

마지막으로 LIMIT 명령어로 데이터 조회개수를 제한했다.

 

문제를 이해할 수 있도록, 아래에 각 명령어를 실행했을 때의 결과를 스텝별로 정리해두었다.

문제풀이에 참고하길 바란다.

테스트에 사용된 ANIMAL_INS
테스트에 사용된 ANIMAL_OUTS

더보기

<MySQL 쿼리문>

CREATE TABLE ANIMAL_INS
(
  ANIMAL_ID VARCHAR(32) PRIMARY KEY,
  ANIMAL_TYPE VARCHAR(32) NOT NULL,
  DATETIME DATETIME NOT NULL,
  INTAKE_CONDITION VARCHAR(32) NOT NULL,
  NAME VARCHAR(32),
  SEX_UPON_INTAKE VARCHAR(32) NOT NULL
);

INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A354597', 'Cat', '2014-05-02 12:16:00', 'Normal', 'Ariel', 'Spayed Female');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A373687', 'Dog', '2014-03-20 12:31:00', 'Normal', 'Rosie', 'Spayed Female');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A412697', 'Dog', '2016-01-03 16:25:00', 'Normal', 'Jackie', 'Neutered Male');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A413789', 'Dog', '2016-04-19 13:28:00', 'Normal', 'Benji', 'Spayed Female');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A414198', 'Dog', '2015-01-29 15:01:00', 'Normal', 'Shelly', 'Spayed Female');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A368930', 'Dog', '2014-06-08 13:20:00', 'Normal', '', 'Spayed Female');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A423211', 'Dog', '2016-03-29 16:00:00', 'Normal', 'Joy', 'Spayed Female');

CREATE TABLE ANIMAL_OUTS
(
  ANIMAL_ID VARCHAR(32) PRIMARY KEY,
  ANIMAL_TYPE VARCHAR(32) NOT NULL,
  DATETIME DATETIME NOT NULL,
  NAME VARCHAR(32),
  SEX_UPON_OUTCOME VARCHAR(32) NOT NULL
);

INSERT INTO ANIMAL_OUTS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME)
VALUES ('A354597', 'Cat', '2014-05-02 12:16:00', 'Ariel', 'Spayed Female');
INSERT INTO ANIMAL_OUTS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME)
VALUES ('A373687', 'Dog', '2014-03-20 12:31:00', 'Rosie', 'Spayed Female');
INSERT INTO ANIMAL_OUTS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME)
VALUES ('A368930', 'Dog', '2014-06-13 15:52:00', '', 'Spayed Female');

 

1) LEFT JOIN

ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 LEFT JOIN으로 결합했고,

결합 기준은 ANIMAL_ID이다.

ANIMAL_OUTS 테이블에 'ANIMAL_ID = A412697, A413789, A414198, A423211'이 없으므로

오른쪽 4~7행에 null 값으로 조회된 것을 확인할 수 있다. 

SELECT *FROM ANIMAL_INS LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID

LEFT JOIN 실행 결과

 

2) WHERE 조건문

입양을 못 간 동물들을 확인하기 위해, ANIMAL_INS에만 존재하는 데이터들만 조회했다.

이를 위해 ANIMAL_ID를 사용했다.

(ANIMAL_OUTS.ANIMAL_ID IS NULL)

SELECT *FROM ANIMAL_INS LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.ANIMAL_ID IS NULL

WHERE 조건문 적용후 실행 결과

 

3) LIMIT

마지막으로 데이터 3개만 조회하기 위하여, 

LIMIT 명령어를 사용했다.

(LIMIT 3)

SELECT *FROM ANIMAL_INS LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.ANIMAL_ID IS NULL
ORDER BY ANIMAL_INS.DATETIME ASC
LIMIT 3

LIMIT 적용후 실행 결과

 

필자는 본 문제를 LEFT JOIN 명령어를 사용해서 풀었지만,

RIGHT JOIN 명령어로도 문제 풀이가 가능하다는 점!


My Answer. 

SELECT ANIMAL_INS.NAME, ANIMAL_INS.DATETIME
FROM ANIMAL_INS LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.ANIMAL_ID IS NULL
ORDER BY ANIMAL_INS.DATETIME ASC
LIMIT 3

References. 

MySQL 테스트 사이트:

http://sqlfiddle.com/#!9/0029cc6/3

 

SQL Fiddle | A tool for easy online testing and sharing of database problems and their solutions.

Query Panel Use this panel to try to solve the problem with other SQL statements (SELECTs, etc...). Results will be displayed below. Share your queries by copying and pasting the URL that is generated after each run.

sqlfiddle.com

 

Comments