본문 바로가기

Data Literacy/SQL

Chapter 2. JOIN을 이용한 데이터 조합 - (4) FULL OUTER JOIN

PostgreSQL logo image

 

 

이번 아티클에서는 FULL OUTER JOIN을 배워보겠습니다. FULL이라는 단어에서 느껴지듯, 뭔가 종합적인 JOIN이 이루어지는 것처럼 느껴집니다. 과연 예상이 맞을지, 살펴보겠습니다. 

 

일단 요약해서 설명하자면, 두 개의 테이블을 FULL OUTER JOIN으로 조합하게 된다면 결과적으로는 두 개의 테이블이 JOIN 되어 매칭되면서 출력됩니다. 단, 우리가 배웠던 내용을 기반으로 설명한다면 INNER JOIN + LEFT OUTER JOIN + RIGHT OUTER JOIN의 결과물이 모두 출력된다고 이해할 수 있습니다. 

 

위의 그림처럼, 두 테이블에서 조건에 해당하는 모든 데이터의 합집합과 비슷한 개념이라고 생각해 주시면 되겠습니다. 그럼 일단 새로운 테이블을 생성하고, 그 테이블에 FULL OUTER JOIN을 적용하여 새로운 테이블을 생성해 보겠습니다. 

 

create table if not exists departments2
(
	department_id serial primary key,
	department_name varchar (255) not null
);

create table if not exists employees3
(
	employee_id serial primary key,
	employee_name varchar (255),
	department_id integer
);

 

insert into departments2(department_name) values
('Sales'), ('Marketing'), ('HR'), ('IT'), ('Production');

insert into employees3(
	employee_name,
	department_id
)
values
('Bette Nicholson', 1),
('Christian Gable', 1),
('Joe Swank', 2),
('Fred Constner', 3),
('Sandra Kilmer', 4),
('Julia Mcqueen', null);

select * from departments2

select * from employees3

 

 

 

 

위의 두 개의 테이블을 잘 기억해 주시기 바랍니다. 일단 위의 부서 현황과 임직원 리스트를 보면, 두 가지 특징이 있습니다. 우선 직원 중 6번 Julia Mcqueen의 할당된 부서 ID가 없습니다. 또한, 부서 중 'Production' 부서에 소속된 임직원이 없습니다.

 

그럼 여기서 기본적인 조인을 진행해 보겠습니다. 우리가 앞서 진행했던 실습과 마찬가지로, 임직원 리스트를 나열하고 거기에 매칭되는 부서의 이름을 차례로 표시하도록 해보겠습니다. OUTER JOIN을 사용하는 방식도 그대로이고, 임직원 리스트에 기재된 부서 ID를 기반으로 부서 이름을 표시하기로 했으니 ON 조건 쿼리에는 부서 테이블을 조건식 좌측에 적어야 합니다. 

 

select e.employee_id,
       e.employee_name,
       d.department_id,
       d.department_name
  from employees3 e
  full outer join departments2 d
    on d.department_id = e.department_id;

 

위와 같은 쿼리를 작성했습니다. 임직원 테이블에서 부서 ID를 매칭하여 각 임직원의 부서를 출력하도록 쿼리를 작성했습니다. OUTER JOIN을 FULL OUTER JOIN으로 작성한 부분을 제외하면, 앞서서 배운 OUTER JOIN과 크게 다르지 않습니다. 그럼 결과를 살펴보겠습니다. 

 

 

우선 1행부터 5행까지는 우리가 익히 알고 있는 방식으로 매칭된 행이 출력되었습니다. 그럼 6행은 어떨까요? Julia Mcqueen은 소속 부서가 없어서 DEPARTMENT_ID가 NULL이었습니다. 그 값이 그대로 출력되었고, 반대로 7행에서는 Production 부서에 소속된 임직원이 아예 없어 NULL 인 상태가 그대로 표시되었습니다. 

 

FULL OUTER JOIN을 실행하니 완벽하게 매칭된 값 이외의 경우도 모조리 출력되는 것을 확인할 수 있습니다. INNER JOIN과 LEFT/RIGHT OUTER JOIN을 통해 얻을 수 있는 모든 값들이 출력되었다고 보시면 됩니다.

 

 


 

그럼 위의 예시에서, RIGHT ONLY / LEFT ONLY를 출력하는 방식도 예제를 만들어 보겠습니다. 여기서 RIGHT/LEFT ONLY가 무엇을 의미할까요? 위의 출력된 이미지 중 6번, 7번 행을 살펴보겠습니다. 6번 행은 LEFT 테이블만 값이 있고, 7번 행의 경우 RIGHT 테이블만 값이 있습니다. 

 

여기서 대충 눈치채셨겠지만, 6번 행이 LEFT ONLY를 의미하고 7번 행이 RIGHT ONLY를 의미합니다. 자, 이제 실전에서 예를 들어보겠습니다. 우리가 전체 임직원 / 부서 리스트가 있는 상태인데 만일 "소속 부서가 없는 직원"을 출력하거나 "소속 임직원이 없는 부서"를 골라서 출력하고 싶을 때, 위의 RIGHT/LEFT ONLY를 사용할 수 있겠죠. 

 

우선 [소속 직원이 없는 부서]를 출력해 보겠습니다. 위의 테이블 형태를 기준으로 보았을 때, RIGHT ONLY가 되겠네요.

 

select e.employee_id,
       e.employee_name,
       d.department_id,
       d.department_name
  from employees3 e
  full outer join departments2 d
    on d.department_id = e.department_id
 where e.employee_name is null;

 

 

반대로 [소속 부서가 없는 직원]을 골라서 출력해 보겠습니다. 여기서는 LEFT ONLY가 되겠네요.

 

select e.employee_id,
       e.employee_name,
       d.department_id,
       d.department_name
  from employees3 e
  full outer join departments2 d
    on d.department_id = e.department_id
 where d.department_name is null;