SQL 레벨업 - 6장 결합 (1/3)

2018-11-20

18강 기능적 관점으로 구분하는 결합의 종류

1. 크로스 결합 - 모든 결합의 모체

  • 크로스 결합의 작동
SELECT * FROM Employees CROSS JOIN Departments;

모든 경우의 수에 대한 결과 값이 출력 된다.

회사 테이블의 레코드 6개, 부서 테이블의 레코드가 4개 있다면 24개의 결과가 나온다.

크로스 결합은 수학에서 데카르트 곱이라고 불리우는 연산으로, 2개 테이블의 레코드에서 가능한 모든 조합을 구하는 연산이다.

  • 크로스 결합이 실무에서 사용되지 않는 이유
    1. 이러한 결과가 필요한 경우가 없다.
    2. 비용이 매우 많이 드는 연산이다.
  • 실수로 사용한 크로스 결합
SELECT *
	FROM Employees, Departments;

결합 조건이 없으면 DBMS는 어쩔 수 없이 두 개 의 테이블에서 나올 수 있는 모든 조합을 만들어 버린다. 주의하자

2. 내부 결합 - 왜 ‘내부’ 라는 말을 사용할까?

  • 내부 결합의 작동
SELECT E.emp_id, E.emp_name, E.dept_id, D.dept_name
	FROM Employees E INNER JOIN Departments D
	ON E.dept_id = D.dept_id;

내부 결합의 결과는 크로스 결합의 일부(부분 집합)이다. 때문에 ‘내부’라는 표현을 사용한다. 내부는 ‘데카르트 곱의 부분 집합’이라는 의미이다.

  • 내부 결합과 같은 기능을 하는 상관 서브쿼리
-- 위 쿼리문을 상관 서브쿼리로 변경
SELECT E.emp_id, E.emp_name, E.dept_id,
	(SELECT D.depth_name
    	FROM Departments D
    	WHERE E.depth_id = D.dept_id) AS dept_name
FROM Employees E;    	

상관 서브쿼리 내부에서 결합 조건을 기술하고 있는데, dept_id는 부서 테이블의 기본 키이므로 조건으로 지정하면 레코드가 한 개로 한정될 것이 보장된다. 따라서 기본 키를 사용하면 상관 서브쿼리를 스칼라 서브쿼리로 사용할 수 있다.

하지만 결합을 사용하는게 상관 서브쿼리를 사용하는것보다 실행 비용에서 이득이다.

3. 외부 결합 - 왜 ‘외부’라는 말을 사용할까?

내부가 ‘데카르트 곱의 부분집합’ 이라는 의미를 함축한 것이었으므로, 외부는 ‘데카르트 곱의 부분 집합이 아니다’ 라는 의미이다. 다만 데이터 상태에 따라 경우에 따라서 데카르트 곱의 부분 집합 이 되기도 한다.

  • 외부 결합의 작동
    1. 왼쪽 외부 결합
    2. 오른쪽 외부 결합
    3. 완전 외부 결합

왼쪽 외부 결합과 오른쪽 외부 결합은 실질적으로 같은 기능을 가진다. 차이점은 마스터 테이블이 왼쪽에 적으면 왼쪽 외부 결합, 오른쪽에 적으면 오른쪽 외부 결합이라는 점이다.

-- 왼쪽 외부 결합(왼쪽 테이블이 마스터)
SELECT E.emp_id, E.emp_name, E.dept_id, D.dept_name
	FROM Departments D LEFT OUTER JOIN Employees E
	ON E.dept_id = D.dept_id;

-- 오른쪽 외부 결합(오른쪽 테이블이 마스터)
SELECT E.emp_id, E.emp_name, E.dept_id, D.dept_name
	FROM Employees E RIGHT OUTER JOIN Departments D
	ON E.dept_id = D.dept_id;


-- 실행 결과
emp_id | emp_name | dept_id | dept_name
-------*----------*---------*----------
001    |     	mh|	      10|       총무
002    |     	dd|	      11|       인사
003    |     	aa|	      12|       개발
NULL   |      NULL|       13|       영업
-- 마지막 레코드는 크로스 결합에서 생성되지 않았다

마스터 테이블 쪽에만 존재하는 키가 있을 때는 해당 키를 제거하지 않고 결과에 보존한다. 따라서 키를 모두 가진 레이아웃의 리포트를 만들 때 자주 사용한다.

4. 외부 결합과 내부 결합의 차이

외부 결합에서 마지막에 보이는 하나의 행만 결과가 다르다. 이는 내부 결합은 물론 크로스 결합의 결과에도 없던 레코드이다. 이 레코드가 ‘외부 결합’에서의 ‘외부’의 의미가 된다. 외부 결합이 마스터 테이블의 정보를 모두 보존하고자 NULL을 생성하기 때문이다. 반면 크로스 결합과 내부 결합은 NULL을 생성하지 않는다.

join_type

5. 자기 결합 - ‘자기’ 란 누구일까?

자기 결합(Self Join)은 문자 그대로 자기 자신과 결합하는 연산이다. 간단하게 말하면 같은 테이블(또는 같은 뷰) 를 사용해 결합하는 것이다.

앞선 세 종류의 결합과는 분류 자체가 다르다. 자기 결합은 생성되는 결과를 기준으로 분류하는 것이 아닌 연산의 대상으로 무엇을 사용하는지에 따른 분류이다. 따라서 ‘자기 결합 + 크로스결합’, ‘자기결합 + 외부결합’ 같은 조합이 가능하다. ‘외부 결합 + 내부 결합’ 같은 조합이 불가능한것과 대조적이다.

  • 자기 결합의 작동
SELECT D1.digit + (D2.digit * 10) AS seq
FROM Digits D1 CROSS JOIN Digits D2;


-- 실행 결과
seq
---
  0
  1
  2
...
 97
 98
 99

Digits 테이블에 0부터 9까지 10개의 레코드가 등록되어있다고 가정한다면 양쪽 모두 10개 이므로 10x10이 출력된다.

  • 자기 결합의 사고방식

자기결합을 수행하는 경ㅇ우는 일반적으로 같은 테이블에 별칭을 붙여 마치 다른 테이블인 거서럼 다룬다. 따라서 D1과 D2를 우연히 같은 데이터를 저장하고 있는 서로 다른 테이블이라고 봐도 좋다.