1. 조인의 이해
1.1 조인이란?
join(조인) 또는 결합 구문은 한 데이터베이스 내의 여러 테이블의 레코드를 조합하여 하나의 열로 표현한 것이다. 따라서 조인은 테이블로서 저장되거나, 그 자체로 이용할 수 있는 결과 셋을 만들어 낸다. JOIN은 2개의 테이블에서 각각의 공통값을 이용함으로써 필드를 조합하는 수단이 된다. ANSI 표준 SQL은 네 가지 유형의 JOIN을 규정한다. [위키백과]
- INNER JOIN
- OUTER JOIN
- LEFT JOIN
- RIGHT JOIN
1과목에서 배운 관계를 다시 한 번 떠올려 봅시다. 관계를 맺는다는 것은 부모의 식별자를 자식이 상속하고, 상속된 속성을 매핑키로 활용하여 데이터를 결합할 수 있다는 의미입니다. SQL에서는 이런 형태의 결합을 조인(Join)이라고 합니다. 신입 개발자 면접 시 조인과 관련한 질문은 단골 소재입니다.
1.2 JOIN SQL
다음은 데이터 표준화 과정의 하나인 표준 도메인 사전을 정의할 때 꼭 필요한 정보인 도메인 그룹과 인포타입의 샘플 데이터입니다. 표준 사전을 만들 때는 표준 단어 → 표준 도메인 → 표준 용어 순으로 정의하게 되며 도메인은 속성이 가질 수 있는 값의 범위입니다. 도메인은 하나의 인포타입과 매핑됩니다. 앞으로 표준화 관련 예제를 사용하여 표준화에 대한 내용도 함께 학습하려고 합니다. 아래 링크를 클릭하시면 더 많은 정보를 확인할 수 있습니다.
dataonair.or.kr 👈 클릭
- 도메인그룹
도메인그룹ID | 그룹명 | 코드도메인여부 |
---|---|---|
1100001 | 수량 | N |
1100002 | 코드 | N |
- 인포타입
인포타입ID | 타입명 | 논리데이터타입 | 데이터길이 | 소수점자릿수 | 도메인그룹ID |
---|---|---|---|---|---|
1100003 | CD_VAR0001 | VARCHAR | 1 | NULL | 1100002 |
1100004 | CD_VAR0002 | VARCHAR | 2 | NULL | 1100002 |
1100005 | CD_VAR0003 | VARCHAR | 3 | NULL | 1100002 |
1100006 | QN_NUM0005 | NUMBER | 5 | NULL | 1100001 |
SELECT A.그룹명
,B.타입명
,B.논리데이터타입
FROM 도메인그룹 A, 인포타입 B
WHERE A.도메인그룹ID = B.도메인그룹ID;
2. 계층형 데이터 모델
자기 자신과 관계가 발생하는 경우도 있습니다. 계층형 데이터 모델이란 계층 구조를 가진 모델을 의미합니다. 아래의 테이블과 쿼리를 보면 데이터 간에 계층 구조가 있음을 알 수 있습니다. 이렇게 데이터 간에 계층 구조가 존재할 때 계층형 데이터 모델이 발생합니다.
- 도메인
도메인ID | 도메인명 | 도메인그룹ID | 인포타입ID | 부모도메인ID |
---|---|---|---|---|
1100007 | 엑터상세유형코드 | 1100002 | 1100005 | NULL |
1100008 | 개인상세유형코드 | 1100002 | 1100005 | 1100007 |
1100009 | 법인상세유형코드 | 1100002 | 1100005 | 1100007 |
-- Self-Join
SELECT B.도메인명 AS 부모도메인명
,A.도메인명
FROM 도메인 A, 도메인 B
WHERE A.도메인ID = '1100008'
AND A.부모도메인ID = B.도메인Id;
3. 상호배타적 관계
상호배타적 관계는 개념만 숙지하고 가겠습니다. 아래 모델을 보면 괄호가 있습니다. 이는 상호배타적 관계를 의미합니다. 주문 엔터티의 개인/법인번호 속성은 개인번호 또는 법인번호 하나만 상속할 수 있습니다.
상품구매내역 엔터티의 특정 데이터를 고객명과 함께 보여주고 싶다면 아래와 같이 작성해 볼 수 있습니다.
-- JOIN 결과가 없다면 공집합(NO ROWS)
SELECT B.개인고객명 AS 고객명
,A.주문번호
FROM 주문 A, 개인고객 B
WHERE A.주문번호 = '1100012'
AND A.고객구분코드 = '01' -- 개인: 01
AND A.개인/법인번호 = B.개인번호
UNION ALL
SELECT B.법인명 AS 고객명
,A.주문번호
FROM 주문 A, 법인고객 B
WHERE A.주문번호 = '1100012'
AND A.고객구분코드 = '02' -- 법인: 02
AND A.개인/법인번호 = B.법인번호;
-- JOIN 결과가 없다면 NULL값을 가진 한 건의 ROW
SELECT COALESCE(B.개인고객명, C.법인명) AS 고객명
,A.주문번호
FROM 주문 A
LEFT OUTER JOIN 개인고객 B
ON A.개인/법인번호 = B.개인번호
LEFT OUTER JOIN 법인고객 C
ON A.개인/법인번호 = C.법인번호
WHERE A.주문번호 = '1100012';
References
SQL 전문가 가이드(2020 개정판)
https://dataonair.or.kr
https://www.wikipedia.org