개발하는 햄팡이

[SQL] JOIN - 여러가지 테이블에서 데이터를 한번에 조회하는 방법 본문

Database/MySQL

[SQL] JOIN - 여러가지 테이블에서 데이터를 한번에 조회하는 방법

hampangee 2025. 4. 14. 16:51

1. JOIN이란?

JOIN은 내가 보고 싶은 데이터들이 각기 다른 테이블에 위치할 때 한 번에 조회하기 위해 사용되는 명령어이다.

예를 들어, Members 테이블에 회원 정보가, Orders 테이블에 주문 정보가 저장되어 있을 때, 특정 회원의 주문 내역을 함께 조회하고 싶다면 JOIN을 사용한다.

예시 상황: 쇼핑몰 시스템에서 회원별 구매 내역을 보고자 할 때

  • Members 테이블: 회원 ID, 이름, 이메일 등
  • Orders 테이블: 주문 ID, 회원 ID, 상품명, 주문일자 등

 

Members 테이블

member_id name email
1 Alice alice@example.com
2 Bob bob@example.com
3 Charlie charlie@example.com

 

Orders 테이블

order_id member_id product order_date
101 1 Laptop 2025-01-15
102 1 Mouse 2025-02-02
103 2 Keyboard 2025-02-20
104 4 Monitor 2025-03-01

 

이렇게 생겼다고 가정하고 JOIN의 종류와 그 예시에 대해서 살펴보자.

 

 

2. JOIN의 종류

JOIN의 종류는 아래와 같다. 

크게 보면 inner join, outer join, cross join이 있고,

outer join 안에 left, right, full join이 있는 형태이다.

     
INNER JOIN 두 테이블의 공통 조건을 만족하는 행만 반환 교집합
LEFT (OUTER) JOIN 왼쪽(첫 번째) 테이블의 모든 행 + 일치하는 오른쪽 테이블 행 왼쪽 테이블 우선, 오른쪽 매칭 없으면 NULL
RIGHT (OUTER) JOIN 오른쪽(두 번째) 테이블의 모든 행 + 일치하는 왼쪽 테이블 행 오른쪽 테이블 우선, 왼쪽 매칭 없으면 NULL
FULL (OUTER) JOIN 양쪽 테이블의 모든 행을 반환 합집합, 매칭 없는 쪽은 NULL
CROSS JOIN 두 테이블의 모든 행 조합 행 수 = 테이블 A

 

2.1. INNER JOIN

Inner join은 결합 시 두 테이블 간에 지정한 조건을 만족하는 행만 결합하여 반환한다. 즉, 교집합과 같다.

만약 쿼리가 아래와 같다면?

SELECT
  m.member_id AS 회원ID,
  m.name    AS 회원이름,
  o.order_id AS 주문ID,
  o.product  AS 상품명,
  o.order_date AS 주문일자
FROM Members AS m
INNER JOIN Orders AS o
  ON m.member_id = o.member_id;

지정 조건 ON m.member_id = o.member_id 에 따라

MembersOrders 테이블에서 member_id 값이 동일한 데이터만 조회된다.

결과는 아래와 같다.

회원ID 회원이름 주문ID 상품명 주문일자
1 Alice 101 Laptop 2025-01-15
1 Alice 102 Mouse 2025-02-02
2 Bob 103 Keyboard 2025-02-20

 

2.2. LEFT JOIN

left join은 말 그대로 왼쪽 테이블을 기준으로 매칭되는 Orders 데이터를 가져오는 방법이다.

왼쪽 테이블은 Query의 기준이 되는 FROM에 위치한 테이블을 말한다.

 

member별로 어떤 주문을 했는지 알고 싶을때 쿼리를 아래와 같이 쓴다.

SELECT
  m.member_id,
  m.name,
  o.order_id,
  o.product,
  o.order_date
FROM Members AS m
LEFT JOIN Orders AS o
  ON m.member_id = o.member_id;

 

Query가 위와 같다고 할 때 결과는 아래와 같다.

member_id name order_id product order_date
1 Alice 101 Laptop 2025-01-15
1 Alice 102 Mouse 2025-02-02
2 Bob 103 Keyboard 2025-02-20
3 Charlie NULL NULL NULL

→ Members 테이블을 기준으로 하여 orders 데이터를 조회하기 때문에

Alice는 두 항목이 일치하여 두 개의 데이터가 반환되었고, Charlie는 주문한 내역이 없어 null로 나오는 것.

 

2.3. RIGHT JOIN

Right join은 left join과 반대.

Left join에서 예시로 사용한 쿼리를 Right join으로 바꾸어 실행하면 아래와 같은 데이터가 반환된다.

member_id name order_id product order_date
1 Alice 101 Laptop 2025-01-15
1 Alice 102 Mouse 2025-02-02
2 Bob 103 Keyboard 2025-02-20
NULL NULL 104 Monitor 2025-03-01

 

아까와는 반대로 104번 주문번호는 회원 4와 일치하는데 일치하는 회원이 테이블에 없으므로 null로 반환되는 것.

 

2.4. FULL JOIN

full join은 간단하게 합집합과 같다.

left join 결과 null로 나왔던 데이터(Charlie의 구매내역이 null인 행)와

right join 결과 null로 나왔던 데이터(구매자를 알 수 없어 null로 표시된 Monitor 구매내역) 전부 반환해준다.

member_id name order_id product order_date
1 Alice 101 Laptop 2025-01-15
1 Alice 102 Mouse 2025-02-02
2 Bob 103 Keyboard 2025-02-20
3 Charlie NULL NULL NULL
NULL NULL 104 Monitor 2025-03-01

 

2.5. CROSS JOIN (+ SELF JOIN)

CROSS JOIN은 두 테이블 간 만들어질 수 있는 모든 조합을 생성한다.

예를 들어, 회원이름와 상품명을 cross join을 한다고 하면

쿼리는 아래와 같고, (회원 수 * 상품 수)개 의 행이 반환된다.

 

예시에서는 회원이 3명 상품이 4개이므로 12개의 행이 만들어진다.

SELECT
  m.name   AS 회원이름,
  o.product AS 상품명
FROM Members AS m
CROSS JOIN Orders AS o;
회원이름 상품명
Alice Laptop
Alice Mouse
Alice Keyboard
Alice Monitor
Bob Laptop
Bob Mouse

 

12개의 행 중에서 6개를 추려온 부분이다.

위와 같이 모든 가능한 경우를 만들어서 반환한다.

 

위에서는 계속 조건을 기준으로 일치하냐 아니냐를 따져 그에 맞추어 결과가 반환되었는데,

cross join은 아무런 관계가 없는 항목에 대해서도 결합한다.

 

 

2.6. + SELF JOIN

join의 종류는 크게 5개로 되어있지만 이를 활용한 SELF JOIN도 존재한다.

A테이블과 B테이블을 join하는 이유는 A와 B의 어떠한 칼럼간의 관계를 살펴보기 위해서이다.

 + Self join도 마찬가지로 자기 자신의 칼럼 중에서 관계를 살펴보기 위해 사용된다.

 

특이한 부분이 있다면 self join을 cross join의 형태로 할 땐 이런식으로 한다는 것.

SELECT m1.name, m2.email
FROM Members m1, Members m2

둘다 같은 테이블을 참조하기 때문에 꼭 Alias를 써줘야한다. 


이렇게 join에 대한 개념을 정리했는데 사실 막상 실제로 써보는 것과 이론은 다르다는 것...

이렇게 공부하고도 실제로 사용하려면 많은 경험이 필요한 것 같다.

고민해서 결국 원하는 답을 얻어낼수는 있지만 

아직은 시간이 좀 걸린다..