본문 바로가기

Data Literacy/SQL

Chapter 2. JOIN을 이용한 데이터 조합 - (1) INNER JOIN

PostgreSQL logo image

 

 

우선 당연하겠지만, JOIN이란 명령어 자체에 대한 정의가 이루어져야 JOIN과 관련된 내용을 배울 수 있을 것입니다. 기본적으로 SQL에서 JOIN은 [한 DB내의 두 개 이상의 테이블에서 레코드를 조합하여 새로운 하나의 테이블을 만들어내는] 구문입니다. JOIN을 두고 "결합"구문이라고도 하는 이유입니다. 

 

굳이 이러한 결합 기능이 SQL에서 존재하고, 사용하는 이유가 무엇일까요? 따로 설명하지 않더라도 개발 경험이 어느 정도 있거나, 이러한 구조에 대한 이해도가 있다면 금방 이해가 가겠지만, 이러한 관념 자체가 없는 분들이라면 추후에 DB 테이블을 직접 생성하고 구조를 짜는 단계까지 갔을 때 쉽게 이해하실 수 있을 것이라고 생각합니다. 

 

현 단계에서는, 다음 내용만 이해하고 넘어가면 되겠습니다. 회원 정보 테이블 / 결제 정보 테이블 / 상품 정보 테이블이 모두 각각 나뉘어 관리되고 있는 상황이라고 가정해 보겠습니다. 그런데 어떤 로그인한 회원이 MY 페이지에서 자신이 결제해서 구매한 상품 정보를 본다고 했을 때, 각각의 테이블에 있는 정보를 하나씩 전부 검증해서 가져올까요? 누가 봐도 아닐 것 입니다. 

 

예를 들어 John이라는 회원의 > 결제 정보를 클릭하면 > 결제 하면서 샀던 상품을 보여준다라는 기능을 생각해 보겠습니다. 지금 위에서 말했다시피 세 개의 테이블이 각각 나뉘어 있는 상태이기 때문에 세 개의 테이블에 있는 정보를 각각 추출해 병합해서 하나의 테이블로 만들고, 그 데이터를 출력해야 합니다. 

 

이런 조건이 있다고 가정했을 때, 이 분리된 테이블에서 정보를 조건에 맞게 매칭해 뽑아주는 기능을 하는 것이 이 JOIN 쿼리입니다. 

 

JOIN은 결합 조건이 다양한 만큼 여러가지 분류가 있습니다. 우선은 가장 기본적인 INNER JOIN에 대해서 살펴보겠습니다. 

 

 


 

 

○ INNER JOIN(내부 조인)

 

INNER JOIN의 경우 두 개 이상의 테이블에 ON을 통해서 조건 구문을 주고 이 조건에 부합하는 레코드를 리턴하게 만드는 가장 기본적인 쿼리입니다. 간단하게 예를 들어서 설명해 보겠습니다. 

 

우리에게 주어진 확인 과제가 다음과 같다고 생각해 봅시다. 

 

Q. 우리는 지금 고객 명단(CUSTOMER) 테이블과 결제 내역(PAYMENT) 테이블이 각각 분리되어 있습니다. 편의상 필요하니, 한 개의 테이블에서 각 고객의 구매 건별로 고객 아이디 / 성 / 이름 / 메일주소 /  구매 날짜를 한꺼번에 볼 수 있게 해 주세요.

 

자, 그럼 이런 경우에는 현재의 테이블 구조가 어떻게 되어있는지 파악이 중요합니다. CUSTOMER 테이블과 PAYMENT 테이블을 각각 뜯어보면 다음과 같습니다. 

 

 

 

위에서 확인하다시피 CUSTOMER 테이블과 PAYMENT 테이블에는 공통으로 사용되는 칼럼이 있습니다. 바로 'CUSTOMER_ID'죠? 그럼 INNER JOIN을 통해서 CUSTOMER_ID를 기준으로 사용해 데이터를 출력하면 된다는 점을 쉽게 도출할 수 있습니다. 

 

이를 쿼리로 조합해 사용해 보겠습니다. 

 

 

select c.customer_id ,
       c.first_name ,
       c.last_name ,
       c.email ,
       p.amount ,
       p.payment_date 
  from customer c inner join payment p 
    on c.customer_id = p.customer_id

 

위와 같은 조건으로 출력하면, 새로운 테이블이 아래처럼 등장하게 됩니다. 

 

 

원하는 칼럼 내역이 지정한 대로 설정되고, 고객 정보와 결제 정보가 매칭되어 새롭게 확인이 가능한 데이터 테이블이 생성되었죠? 여기까지 왔으면 거의 다 한 것입니다. 여기에 약간의 부가적인 기능만 더해주면 됩니다. 

 

위와 같이 데이터를 뽑는데, 여기서 한 가지 맹점은 '모든 고객'의 데이터가 뽑혀서 나왔다는 점입니다. 우리가 특정 고객 1명(이름이나 CUSTOMER_ID 특정)을 뽑아야 할 때는 어떻게 해야 할까요? 여기서는 WHERE 구문을 써주면 간단합니다. 아래처럼요.

 

select c.customer_id ,
       c.first_name ,
       c.last_name ,
       c.email ,
       p.amount ,
       p.payment_date 
  from customer c inner join payment p 
    on c.customer_id = p.customer_id
 where c.first_name = 'Peter' or c.first_name = 'Alex';

 

 

위처럼 WHERE 구문을 통해서 조건을 세분화해 주니, 일정한 조건으로도 JOIN을 진행한 테이블 결괏값을 얻을 수 있습니다. 

 

 

자, 여기서 조건이 더 추가될 수 있습니다. 만일, 여기에 하나의 테이블을 더 조합하여 정보를 표시한다면 어떨까요? 예를 들어 PAYMENT 정보에 해당 결제를 처리한 담당자(STAFF) 정보가 기록되고 있습니다. 이를 통해서, 해당 결제 건을 처리한 스태프 FIRST_NAME과 LAST_NAME을 표시한다면 어떻게 해야 할까요? 

 

간단하게 INNER JOIN을 한 번 더 적용해 주시면 됩니다. 아래 예시를 보겠습니다. 

 

select c.customer_id ,
       c.first_name ,
       c.last_name ,
       c.email ,
       p.amount ,
       p.payment_date ,
       s.first_name as stf_first_name,
       s.last_name as stf_last_name
  from customer c 
 inner join payment p 
       on c.customer_id = p.customer_id
 inner join staff s 
       on p.staff_id = s.staff_id

 

 

위와 같이 테이블 세 개가 각각의 공통 정보를 물고 물리는 구조로 추출되었습니다.