CodingSpace

[프로그래머스/SQL] 있었는데요 없었습니다 (feat. JOIN, LEFT JOIN, RIGHT JOIN) 본문

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

[프로그래머스/SQL] 있었는데요 없었습니다 (feat. JOIN, LEFT JOIN, RIGHT JOIN)

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

Problem. 있었는데요 없었습니다


Link.

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

 

코딩테스트 연습 - 있었는데요 없었습니다

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 테이블

관리자의 실수로 일부 동물의 입양일이 잘못 입력되었습니다.

보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름을 조회하는 SQL문을 작성해주세요.

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


Key Point. 

쉽게 표현하자면, JOIN는 데이블을 관련된 필드들을 기준으로 결합하는데 사용되는 명령어이다.

MySQL에서는 JOIN 명령어로 테이블을 결합할 수 있으며 결합 조건은 ON 명령어로 설정할 수 있다.

MySQL에서 많이 사용되는 JOIN 명령어 종류는 아래와 같다:

  • JOIN (=INNER JOIN)
  • LEFT JOIN
  • RIGHT JOIN

위의 명령어들을 ANIMAL_INS, ANIMAL_OUTS 테이블을 이용해 살펴보겠습니다.

 

테스트에 사용된 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 ('A350276', 'Cat', '2017-08-13 13:50:00', 'Normal', 'Jewel', 'Spayed Female');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A381217', 'Dog', '2017-08-13 13:50:00', 'Sick', 'Cherokee', 'Neutered Male');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A381300', 'Dog', '2017-08-18 15:50:00', 'Normal', 'Joy', 'Spayed Female');
INSERT INTO ANIMAL_INS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE)
VALUES ('A381412', 'Dog', '2017-08-12 16:50:00', 'Sick', 'Peace', 'Neutered Male');

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 ('A350276', 'Cat', '2018-01-28 17:51:00', 'Jewel', 'Spayed Female');
INSERT INTO ANIMAL_OUTS (ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME)
VALUES ('A381217', 'Dog', '2017-06-09 18:51:00', 'Cherokee', 'Neutered Male');

 

1) JOIN (=INNER JOIN)

JOIN는 INNER JOIN와 같은 명령어로, 테이블의 특정 필드 기준으로 공통된 영역만 결합하는 명령어이다. 아래 예시에서는 ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 JOIN 명령어로 결합 했으며,이때 결합 조건은 두 테이블에 ANIMAL_ID가 같은 경우이다. 따라서 Figure 1에서 확인할 수 있듯이, ANIMAL_INS 테이블에는 존재하고 ANIMAL_OUTS 테이블에는 존재하지 않는'ANIMAL_ID = A381300, A381412'는 결합된 테이블에 존재하지 않는다.

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

 

Figure 1. JOIN 명령어 테스트 결과

 

2) LEFT JOIN

LEFT JOIN는 왼쪽 테이블 영역과 특정 필드 기준으로 왼쪽 테이블과 오른쪽 테이블의 공통된 영역을 결합하는 명령어이다. 

아래 예시에서는 ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 LEFT JOIN 명령어로 결합 했으며,

이때 결합 조건은 두 테이블에 ANIMAL_ID가 같은 경우이다. 

따라서 Figure 2에서 확인할 수 있듯이, ANIMAL_INS 테이블에 모든 데이터는 왼쪽 영역에 조회되었으며 ANIMAL_OUTS 테이블에서 ANIMAL_ID 같은 'ANIMAL_ID = A350276, A381217'만 오른쪽 영역에 조회되었다.

이때 ANIMAL_OUTS 존재하지 않는 데이터는 NULL 처리가 된다.

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

 

Figure 2. LEFT JOIN 명령어 테스트 결과

 

3) RIGHT JOIN

RIGHT JOIN는 오른쪽 테이블 영역과 특정 필드 기준으로 왼쪽 테이블과 오른쪽 테이블의 공통된 영역을 결합하는 명령어이다. 

아래 예시에서는 ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 RIGHT JOIN 명령어로 결합 했으며,

이때 결합 조건은 두 테이블에 ANIMAL_ID가 같은 경우이다. 

따라서 Figure 3에서 확인할 수 있듯이, ANIMAL_OUTS 테이블에 모든 데이터는 오른쪽 영역에 조회되었으며 ANIMAL_INS 테이블에서 ANIMAL_ID 같은 'ANIMAL_ID = A350276, A381217'만 왼쪽 영역에 조회되었다.

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

 

Figure 3. RIGHT JOIN 명령어 테스트 결과

 

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

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


My Answer. 

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 OUTS.DATETIME < INS.DATETIME
ORDER BY INS.DATETIME ASC

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