[MS SQL Server] #12_조인(JOIN)이란 무엇일까?, 기초적인 조인들!
안녕하세요. 문범우입니다.
이번 포스팅에서는 조인의 개념에 대해서 알아보고 기초적인 이너조인(Inner JOIN), 아우터조인(Outer JOIN), 크로스조인(Cross JOIN), 셀프조인(Self JOIN)에 대해서 함께 알아보도록 하겠습니다.
1. 조인(JOIN)이란 무엇일까?
DB에서 자주 사용되는 조인이란 개념은 무엇일까요?
조인은 '어울리다'라는 의미를 가지고 있는데 이 말대로, 데이터베이스에서 테이블간의 결합(어울림)을 이야기합니다.
즉, 두개 이상의 테이블에 대해서 결합하여 나타낼 때 조인이라는 것을 이용합니다.
물론 셀프조인에서는 사실 하나의 테이블을 다루는 것입니다. 이에 대해서는 뒤에서 다시 이야기해보겠습니다.
예시데이터를 가지고 살펴보겠습니다.
예시데이터는 이전의 글들에서 사용된 employee 테이블과 department 테이블을 사용하며, employee테이블에 아래와 같이 하나의 데이터를 추가해서 진행해보도록 하겠습니다.
insert into employee (empNo, empName, job, manager, hireDate, salary, commission)
values (1015, '문정진', '대리', 1001, '2009-11-11', 350, 50);
select * from employee;
select * from department;
만약 우리가 사원의 이름과 그가 속한 부서를 알고 싶을 땐 어떻게 해야할까요?
기존의 방법으로 employee 테이블을 통해 조회한다면 다음과 같을 것 입니다.
select empName, deptNo from employee;
하지만 위와 같은 결과는 부서이름이 아니라 부서 코드를 넣어 주었기 때문에 사실 어떤 직원이 어떤 부서에 속했는지 한눈에 보기 힘듭니다.
그런데 어떤 부서코드가 어떤 부서인지에 대한 정보는 department 테이블에 있습니다.
즉, 아래와 같이 하나의 결과에서 employee 테이블과 departement 테이블을 매핑시켜준다면 직원의 이름과 그 직원이 속한 부서의 이름을 보다 쉽게 알 수 있겠죠?
이럴 때 사용되는 것이 바로 조인(JOIN)입니다.
조인의 종류에는 처음에 말씀드렸듯 크게4가지, 이너조인, 아우터조인, 크로스조인, 셀프조인이 있습니다.
그럼 각각의 조인에 대해서 간단하게 알아보겠습니다.
2. 이너 조인(INNER JOIN)
이너조인은 위와 같이 우리가 조인하고자 하는 두개의 테이블에서 공통된 요소들을 통해 결합하는 조인방식입니다. 즉 우리가 위에서 하고자 했던, 직원들의 이름과 부서명을 같이 출력하는데 있어서 사용되는 가장 일반적인 조인이죠. sql에서도 단순히 조인을 사용할때는 암묵적으로 이너조인을 뜻하게 됩니다.
기본적인 이너조인의 SQL형태는 다음과 같습니다.
SELECT table1.col1, table1.col2, ..., table2.col1, table2.col2, ...
FROM table1 [table1의 별칭]
JOIN table2 [table2의 별칭] ON table1.col1 = table2.col2
위의 쿼리에서 대괄호로 사용된 각 테이블의 별칭은 SELECT 절에서 컬럼이름 앞에 붙는 테이블명에서 사용될 수 있습니다.
조인시에 table1과 table2의 어떤 컬럼을 기준으로 할지는 ON 뒤에 작성합니다.
즉 위의 쿼리에서는 table1의 col1 컬럼과 table2의 col2 컬럼이 같은 행들에 대해서 조인을 실시합니다.
그럼 바로 이너조인을 통해서 직원의 이름과 부서명을 함께 출력해보도록 합시다.
select employee.empName, department.deptName
from employee
join department on employee.deptNo = department.deptNo
위와 같이 join문을 통해서 직원의 이름과 부서명을 함께 출력하였습니다.
employee 테이블의 deptNo과 department 테이블의 deptNo이 같은 것끼리 결합하여 직원이름과 부서명을 출력한 것이죠.
3. 아우터 조인(OUTER JOIN)
아우터 조인은 위의 그림과 같이 레프트 아우터 조인, 라이트 아우터 조인 그리고 그 두개를 합친 풀 아우터 조인 총3개가 있습니다.
아우터 조인은 그림과 같이 두 테이블의 공통영역을 포함해 한쪽 테이블의 다른 데이터를 포함하는 조인방식입니다.
아우터 조인을 보다 쉽게 이해하기 위해서 위에서 진행한 이너 조인의 결과를 한번 더 살펴보겠습니다.
위의 결과에서는 사실 누락된 데이터가 있습니다.
employee 테이블을 기준으로 보면 '문정진'이라는 이름의 사원데이터가 누락되어 있으며, department 테이블을 기준으로 보면 '전산부'라는 부서가 누락되어 있습니다.
해당 데이터들이 누락된 이유는 두 테이블간의 공통된 데이터가 없기 때문이죠.
다시말해서, '문정진'사원의 deptNo가 NULL이기 때문에 department 테이블과 공통된 점이 없으며, '전산부' 또한 employee 테이블에서 같은 부서코드를 가진 데이터가 없기 때문에 출력되지 않은 것 입니다.
하지만 이러한 데이터들도 함께 보고싶은 경우가 있고, 그런 경우에 우리는 아우터 조인을 사용합니다.
이때 left와 outer를 정하는 기준은 from절에 적어준 테이블이 left가 되고, join절에 적어준 테이블이 right가 됩니다. 그럼 먼저 부서코드가 NULL이거나 부서테이블의 deptNo과 일치하는 값이 없는 사원까지 출력하는 left 아우터 조인을 쿼리로 확인해보도록 합시다.
select employee.empName, department.deptNamefrom employee
left outer join department on employee.deptNo = department.deptNo
위의 결과를 보시면 이전에 실습했던 이너조인과 달리 '문정진'사원의 데이터도 함께 나오는 것을 확인할 수 있습니다.
그럼 이어서 right 아우터 조인과, full 아우터 조인도 확인해보겠습니다.
select employee.empName, department.deptName
from employee
right outer join department on employee.deptNo = department.deptNo
select employee.empName, department.deptName
from employee
full outer join department on employee.deptNo = department.deptNo
앞에서 설명한 바와 같이 right 아우터 조인은 '전산부' 데이터도 함께 출력되고 있으며, full 아우터 조인은 left 아우터 조인과 right 아우터 조인의 결과를 합친 것과 같습니다.
4. 크로스 조인(CROSS JOIN)
크로스 조인은 사실 앞에서 진행한 이너 조인 및 아우터 조인과 약간의 차이가 존재합니다.
이너 조인과 아우터 조인은 두 테이블간의 특정 기준에 의해 데이터 결합의 결과를 보여주는 방식이었다면, 크로스 조인은 특정 기준 없이, 두 테이블간 가능한 모든 경우의 수에 대한 결합을 결과로 보여주는 방식입니다.
쿼리를 작성할 때에도, 특정한 기준이 필요없으므로 on절이 없어지게 됩니다.
바로 쿼리로 확인해보도록 하겠습니다.
select employee.empName, department.deptName
from employee
cross join department
위와 같이 모든 경우에 수에 대한 결과가 출력되기 때문에 출력 데이터의 행수는 총 15(employee의 모든 행의 개수) * 4(department의 모든 행의 개수) 으로써 60개 입니다.
5. 셀프 조인(SELF JOIN)
셀프조인은 말 그대로 자기 스스로를 결합시키는 조인입니다. 셀프조인은 이너조인 및 아우터 조인, 크로스 조인과 동일한 방식으로 사용될 수 있지만 조인을 할 때에 기본 테이블 이외에 참조하는 테이블이 다른 테이블이 아닌 자기 자신이라는 점이 중요합니다.
셀프조인이 어떤식으로 사용되는지에 대해서 employee 테이블의 데이터를 한번 더 보면서 설명드리겠습니다.
위의 결과를 보면 사원들이 이름과 더불어 manager라는 항목이 존재합니다.
만약 우리가 사원들의 이름과 함께 그 사원의 manager의 이름도 함께 알고 싶다면 어떻게 할까요?
참조할 다른 테이블도 존재하지 않습니다. 이럴 때 우리는 셀프조인을 이용합니다. 즉 employee 테이블, 자기 자신을 조인하는 것 입니다.
이때 우리는 위에서 각 테이블에 대한 별칭을 선택적으로 사용했지만 셀프 조인시에는 별칭을 필수로 입력해주어야 합니다. 같은 테이블을 2개 또는 그 이상 사용하는데 별칭을 정해주지 않으면 혼동되기 때문이죠.
그럼 앞서 말씀드린 상황, 직원의 이름과 그 manager의 이름을 동시에 출력하는 쿼리를 셀프조인 방식으로 확인해보도록 하겠습니다.
select emp1.empNo 사원번호, emp1.empName 직원이름,
emp1.manager 매니저번호, emp2.empName 매니저이름
from employee emp1
join employee emp2 on emp1.manager = emp2.empNo
위와 같이 쿼리의 기본형태는 이너조인과 동일하지만 참조하는 테이블이 from절에 오는 기본 테이블과 동일하며, 별칭을 적어줌으로써 구별하는 모습을 볼 수 있습니다.