[MySQL] INNER JOIN vs LEFT JOIN

dev.Lee·2022년 8월 28일
0
post-thumbnail

지난주에 스터디하려고 준비했던 자료가 날아간 김에 작성하는 벨로그.

데이터리안 강좌 수강 중 계속해서 헷갈리게 발목을 잡는 INNER JOIN과 LEFT JOIN을 간단히 복기하고
프로그래머스 SQL Kit의 JOIN문제를 풀어보았다.
예시의 출처는 코딩교육 티씨피스쿨이다.

JOIN이란?

JOIN이란 두 테이블의 데이터를 일정한 조건으로 연결해 하나의 테이블처럼 만드는 것이다.
여기서 일정한 조건은 주로 두 테이블 사이 공통된 열을 기반으로 행을 결합하는 것으로 이해할 수 있다.
크게 INNER JOIN과 OUTER JOIN으로 나뉘며, OUTER JOIN중에서는 LEFT JOIN이 주로 사용되므로 두 가지의 차이를 비교해보고자 한다.

둘의 차이가 무엇인지를 직관적으로 보기 위해 사용한 다이어그램 이미지는 SQL Join Visualizer를 사용한 것이다.

INNER JOIN

INNER JOIN은 ON 조건문과 함께 사용하며, ON 뒤 조건을 만족하는 레코드를 두 테이블에서 가져온다.
INNER를 생략하고 JOIN만 사용해도 동일한 명령어이다.

  • 예시

위 두 테이블에서 공통된 Name 필드가 일치하는 데이터를 INNER JOIN으로 가져오는 쿼리는 다음과 같다.

SELECT * FROM Reservation
INNER JOIN Customer
	ON Reservation.Name = Customer.Name

Name이 같은 행이 두 테이블에서 각각 불러진 것을 확인할 수 있다.
Reservation 테이블에서 홍길동이 2행 존재하는데 이 경우 Customer 테이블의 홍길동에 대한 레코드가 중복으로 각각 결합된다.

LEFT JOIN

LEFT JOIN은 첫 번째 테이블을 기준으로 두 번째 테이블을 조합한다.
사용법은 INNER JOIN과 같다.

SELECT * FROM Reservation
LEFT JOIN Customer
	ON Reservation.Name = Customer.Name

해당 예제에서는 잘 드러나지 않는데, Name이 일치하면 INNER JOIN처럼 두 테이블의 모든 필드 레코드를 그대로 가져오지만 일치하는 Name이 없는 경우 Customer 테이블의 모든 필드가 NULL로 표시된다.

즉, INNER JOIN은 교집합이기 때문에 조건이 만족하는 -Name이 일치하는 경우의- 행만을 가져온다.
그렇기때문에 조건이 만족하지 않는 -Name이 일치하지 않는- 행은 결과에서 제외된다.

하지만 LEFT JOIN은 첫 번째 테이블을 다 가져옴을 전제로 하여 두 번째 테이블을 가져온다.
따라서 첫 번째 테이블과의 조건을 만족하는 데이터를 두 번째 테이블에서 가져오지 못하는 경우 해당 행을 표시는 하되 두 번째 테이블에서 가져왔어야 할 데이터 영역을 NULL로 채워 표기하는 것이다.

(+)
두 테이블에서 JOIN 조건으로 누락되는 행이 없는 경우 LEFT JOIN과 INNER JOIN이 나타내는 결과가 동일하다. 이런 경우에는 INNER JOIN이 상대적으로 성능이 좋다고 한다.

프로그래머스

프로그래머스 SQL 고득점 Kit의 없어진 기록 찾기 문제를 풀어보았다.

보호소에 들어온 기록(ANIMAL_INS) 테이블과 입양을 보낸 기록(ANIMAL_OUTS) 테이블이 주어지고 입양 간 기록은 있지만 들어온 기록은 없는 아이들을 조회해야 한다.
조회 결과는 위 조건을 만족하는 ANIMAL_ID와 NAME을 나타내면 된다.

조건을 정리하면 다음과 같을 것이다.

  • 입양을 간 기록은 있으므로 ANIMAL_OUTS 데이터를 기준으로 생각하면 된다.
  • ANIMAL_OUTS에 있는 ANIMAL_ID가 ANIMAL_INS에도 있는지 일치 조건을 사용하면 된다. (ON 조건문)
  • 여기서 INNER JOIN대신 LEFT OUTER JOIN이 더 적합한데, 그 이유는 ANIMAL_OUTS를 기준으로 LEFT JOIN해야 ANIMAL_INS에 해당 ID가 없는 행이 NULL로 표시되기 때문이다.
  • 즉 (1) ANIMAL_OUTS를 기준으로 (2) ANIMAL_INS에 같은 ANIMAL_ID가 있는지를 조건으로 하여 JOIN하고 (3) ANIMAL_INS의 ANIMAL_ID가 NULL인 경우를 조회한다.

최종 쿼리는 다음과 같다.

SELECT OUTS.ANIMAL_ID, OUTS.NAME
FROM ANIMAL_OUTS OUTS
LEFT OUTER JOIN ANIMAL_INS INS
    ON OUTS.ANIMAL_ID = INS.ANIMAL_ID
WHERE INS.ANIMAL_ID is NULL
ORDER BY OUTS.ANIMAL_ID
profile
백지를 벗어나고 싶은 학생

0개의 댓글

관련 채용 정보