기록과 정리

SQL-JOIN 본문

IT/DB

SQL-JOIN

zepetto 2021. 9. 1. 20:25

이 글은 '[백문이불여일타] 데이터 분석을 위한 중급 SQL' 강의를 참고하였습니다.

https://www.inflearn.com/course/%EB%B0%B1%EB%AC%B8%EC%9D%B4%EB%B6%88%EC%97%AC%EC%9D%BC%ED%83%80-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D-%EA%B8%B0%EC%B4%88-sql/lecture/29718?tab=note 

 

[백문이불여일타] 데이터 분석을 위한 기초 SQL - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

소개

Join은 두개 이상의 테이블을 합쳐서 봐야하는 경우 사용하는 SQL 문법이다. 

아래 테이블은 이번 글에서 사용할 예시 테이블 ( Users, Orders ) 이다.

 

Users

ID 로그인 아이디 주소
1 A 강서구 방화동
2 B 금천구 시흥동
3 C 강남구 삼성동

Orders

userId 구매상품 가격 결재수단
1 안경 20000 우리카드
2 마우스 100000 국민카드
3 선풍기 50000 계좌이체

INNER JOIN

Id 로그인 아이디 주소 userId 구매상품 가격 결제수단
1 A 강서구 방화동 1 안경 20000 우리카드
2 B 금천구 시흥동 2 마우스 100000 국민카드
3 C 강남구 삼성동 3 선풍기 50000 계좌이체

 

이전에는 

SELECT *

  FROM Users, Orders

WHERE Users.Id = Orders.userId

와 같이 테이블을 두개를 같이 조회를 하여 ( 카티션 프로덕트 : 각 행의 모든 경우의 수를 가져옴 ) 조건을 거는 쿼리를 취했다면 요새는 위와 같은 쿼리를 이용한다고 보면 된다.

 

좋은 조회시 쿼리는

SELECT *

  FROM Users

 INNER JOIN Orders On Users.Id = Orders.userId

 

예약어(INNER JOIN)을 사용해주는 것이 더 명확하다. INNER JOIN은 양쪽 테이블에 데이터가 다 있을 경우, 조회할 수 있다.

예를 들어 Orders에 'userId = 3'인 데이터가 없다고하면 두 테이블을 조인시 3번째 row는 나오지 않게 된다. 집합으로 치면 교집합으로 볼 수도 있다.

 

JOIN은 종류가 많기때문에 각 조인마다 벤다이어그램을 사용하여 이해하기 쉽게 도와주는 사이트가 있다. 해당 조인 영역에 따라 쿼리도 출력 가능하다.

https://sql-joins.leopard.in.ua/

 

SQL Joins Visualizer

Please select how do you want to do SQL JOIN between two table

sql-joins.leopard.in.ua

 

주문 및 고객 테이블을 join 해보자.
이미지가 잘렸지만 주문 및 고객 정보가 같이 나오는 것을 볼수 있다.
Inner join을 얼마든지 추가하여 붙여 사용가능하다.

join key로 사용되는 컬럼들간에 이름이 다른 경우는 얼마든지 생길 수 있다. 이럴 경우, ERD를 분석해서 어떤 관계를 가지고 있는지 ( 1대다 , 1대1 등) 분석하여 파악하도록 하자.

 

OUTER JOIN (LEFT, RIGHT)

INNER JOIN을 제외하고 나머지는 다 OUTER JOIN 이라고 생각하면된다. 그럼 OUTER JOIN은 무엇인지, 왜 필요한지 알아보자.

 

LEFT JOIN

Orders

userId 구매 상품 가격 결제수단
1 안경 20000 우리카드
2 마우스 100000 국민카드

위에 예시를 들었던 Oders 테이블에 3번째 로우가 없어졌다. 여기서 LEFT 조인을 하게 되면

Id 로그인 아이디 주소 userId 구매상품 가격 결제수단
1 A 강서구 방화동 1 안경 20000 우리카드
2 B 금천구 시흥동 2 마우스 100000 국민카드
3 C 강남구 삼성동 NULL NULL NULL NULL

query)

SELECT *

   FROM Users

  LEFT JOIN Orders ON Users.Id = Orders. userId

 

Users(왼쪽) 기준으로 데이터를 전부 뽑고 싶다고 하면 , 다음과 같이 출력을 할 수 있고 Orders(오른쪽)에 데이터가 없는 구간은 NULL로 출력이 된다.  INNER JOIN시에 Orders 레코드가 있는 경우, 즉 한번이라도 주문을 한사람들만 출력이 가능하다. LEFT JOIN의 경우, Users 기준으로 모두 출력한 경우라고 할 수 있다.

 

SELECT *

   FROM Users

  LEFT JOIN Orders ON Users.Id = Orders. userId

WHERE OrderId IS NULL 

 

을 해준다면 한번도 주문을 하지 않은 데이터를 가져올 수도 있다.

 

RIGHT JOIN의 경우는 반대의 경우라고 볼 수 있다. 보기에도 좋은 이유로 LEFT join으로 해결하는 경우가 많다.

 

Full Outer Join의 경우 , LEFT + RIGHT OUTER 조인으로 볼 수있는데 MySQL에서는 지원하지 않기 때문에 LEFT JOIN 과 RIGHT JOIN을 UNION 하여 사용하면된다. 

 

SELF JOIN

자기 테이블을 자기에게 조인을 하는 경우다. 왜 굳이....? 혼자 생각한 결론은 '정규화'가 적절히되지 않은 PK가 FK의 성격을 가진 컬럼을 가진 테이블에서 원하는 데이터를 얻고 싶을 때 사용하는 것으로 보여진다. 예시를 들어 살펴보도록 하자.

https://leetcode.com/problems/employees-earning-more-than-their-managers/

 

Employees Earning More Than Their Managers - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

해당 문제를 살펴보면, 부사수보다 사수가 봉급이 적은 경우를 select하라고 설명되어있다. 

 

Id Name Salary MangerId
1 Joe 70000 3
2 Henry 80000 4
3 Sam 60000 NULL
4 Max 90000 NULL

ManagerId가 본인 사수의 Id값인데, Joe는 Sam , Henry는 Max가 사수로 볼 수 있다.

자기 자신에게 INNER JOIN 을 걸었음.