지난주에 스터디하려고 준비했던 자료가 날아간 김에 작성하는 벨로그.
데이터리안 강좌 수강 중 계속해서 헷갈리게 발목을 잡는 INNER JOIN과 LEFT JOIN을 간단히 복기하고
프로그래머스 SQL Kit의 JOIN문제를 풀어보았다.
예시의 출처는 코딩교육 티씨피스쿨이다.
JOIN이란 두 테이블의 데이터를 일정한 조건으로 연결해 하나의 테이블처럼 만드는 것이다.
여기서 일정한 조건은 주로 두 테이블 사이 공통된 열을 기반으로 행을 결합하는 것으로 이해할 수 있다.
크게 INNER JOIN과 OUTER JOIN으로 나뉘며, OUTER JOIN중에서는 LEFT JOIN이 주로 사용되므로 두 가지의 차이를 비교해보고자 한다.
둘의 차이가 무엇인지를 직관적으로 보기 위해 사용한 다이어그램 이미지는 SQL Join Visualizer를 사용한 것이다.
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은 첫 번째 테이블을 기준으로 두 번째 테이블을 조합한다.
사용법은 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을 나타내면 된다.
조건을 정리하면 다음과 같을 것이다.
최종 쿼리는 다음과 같다.
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