1. 조인(JOIN)
조인은 데이터베이스에서 두 개 이상의 테이블을 관련된 컬럼을 기반으로 결합하여 하나의 테이블로 합치는 메커니즘을 의미합니다.
일반적으로 행들은 기본키(PK)와 외래키(FK)의 연관관계에 의해 조인이 성립됩니다. 하지만 PK, FK의 관계가 없더라도 논리적인 값들의 연관관계만으로도 조인이 성립할 수 있습니다.
1) 동등 조인(Equi Join)
동등 조인은 일반적으로 “조인 키”라고 하는 일치하는 열을 기반으로 두 테이블을 결합하는 조인 작업 유형입니다.
특히 동등 조인은 조인 키가 정확히 일치하는 두 테이블의 행만 반환합니다. 즉, 조인 키 값이 두 테이블에서 동일한 두 테이블의 모든 열을 포함하는 새 테이블을 생성합니다.
예를 들어 “ORDERS”와 “EMPLOYEES”라는 두 개의 테이블이 있다고 가정합니다. 각 주문에는 “EMPLOYEES” 테이블의 직원에 해당하는 EMPLOYEE_ID가 있습니다. 모든 주문 및 관련 고객 정보를 찾으려면 두 테이블의 EMPLOYEE_ID 컬럼에서 동등 조인을 수행하면 됩니다.
아래는 예제 데이터 입니다.
EMPLOYEES
EMPLOYEE_ID |
FIRST_NAME |
LAST_NAME |
1 |
John |
Smith |
2 |
Jane |
Doe |
3 |
Bob |
Johnson |
4 |
Sarah |
Lee |
ORDERS
ORDER_ID |
EMPLOYEE_ID |
ORDER_DATE |
1001 |
1 |
2023-01-01 |
1002 |
2 |
2023-01-15 |
1003 |
3 |
2023-02-01 |
1004 |
4 |
2023-02-15 |
두 테이블 모두에 존재하는 EMPLOYEE_ID 컬럼을 통해 동등 조인을 수행할 수 있습니다.
동등 조인 예제
SELECT EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, ORDERS.ORDER_ID, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES, ORDERS WHERE EMPLOYEES.EMPLOYEE_ID = ORDERS.EMPLOYEE_ID; |
결과는 다음과 같습니다.
동등 조인 결과
LAST_NAME |
FIRST_NAME |
ORDER_ID |
ORDER_DATE |
Smith |
John |
1001 |
2023-01-01 |
Doe |
Jane |
1002 |
2023-01-15 |
Johnson |
Bob |
1003 |
2023-02-01 |
Lee |
Sarah |
1004 |
2023-02-15 |
2) 비동등 조인(Non Equi Join)
비동등 조인은 조인 조건이 같지 않은 비교 연산자를 기반으로 하는 SQL의 조인 유형입니다. 동등 연산자(=)가 아닌 다른 연산자를 사용하여 조인을 수행합니다.
대부분 비동등 조인을 수행할 수 있지만, 설계상의 이유로 수행이 불가능할 수도 있습니다.
아래는 예제 데이터 입니다.
CUSTOMERS
CUSTOMER_ID |
NAME |
AMOUNT |
1 |
John |
450000 |
2 |
Jane |
150000 |
3 |
Bob |
600000 |
4 |
Sarah |
300000 |
GRADE
GRADE |
LOW |
HIGH |
1 |
100000 |
199999 |
2 |
200000 |
299999 |
3 |
300000 |
399999 |
4 |
400000 |
499999 |
5 |
500000 |
599999 |
6 |
600000 |
699999 |
고객의 총 구매액에 대하여 등급을 구하고 싶다면 다음과 같은 비동등 조인 쿼리를 작성할 수 있습니다.
비동등 조인 예제
SELECT CUSTOMERS.NAME, CUSTOMERS.AMOUNT, GRADE.GRADE FROM CUSTOMERS, GRADE WHERE CUSTOMERS.AMOUNT BETWEEN GRADE.LOW AND GRADE.HIGH; |
결과는 다음과 같습니다.
비동등 조인 결과
NAME |
AMOUNT |
GRADE |
John |
450000 |
4 |
Jane |
150000 |
1 |
Bob |
600000 |
6 |
Sarah |
300000 |
3 |
2. 표준 조인
표준 조인은 ANSI/ISO 표준에서 규정한 조인입니다.
표준 조인에는 내부 조인(Inner Join), 외부 조인(Outer Join), 크로스 조인(Cross Join), 자연 조인(Natural Join)이 있습니다.
1) 내부 조인(Inner Join)
내부 조인은 조인 조건에서 동일한 값이 있는 행만 반환하는 조인입니다.
내부 조인 문법
SELECT 컬럼명 FROM 테이블1 INNER JOIN 테이블2 ON 조건절; |
다음과 같은 예제 데이터가 있다고 가정합시다.
EMPLOYEES
EMPLOYEE_ID |
FIRST_NAME |
LAST_NAME |
1 |
John |
Smith |
2 |
Jane |
Doe |
3 |
Bob |
Johnson |
4 |
Sarah |
Lee |
ORDERS
ORDER_ID |
EMPLOYEE_ID |
ORDER_DATE |
1001 |
1 |
2023-01-01 |
1002 |
2 |
2023-01-15 |
1003 |
1 |
2023-02-01 |
1004 |
5 |
2023-02-15 |
EMPLOYEES 테이블에 있는 직원 중 주문 이력이 있는 직원을 확인하고 싶다면 다음과 같이 쿼리를 작성하면 됩니다.
내부 조인 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES INNER JOIN ORDERS ON EMPLOYEES.EMPLOYEE_ID = ORDERS.EMPLOYEE_ID; |
결과는 다음과 같습니다.
내부 조인 결과
EMPLOYEE_ID |
FIRST_NAME |
LAST_NAME |
ORDER_DATE |
1 |
John |
Smith |
2023-01-01 |
2 |
Jane |
Doe |
2023-01-15 |
1 |
John |
Smith |
2023-02-01 |
오라클의 경우 다음과 같이 내부 조인 쿼리를 작성할 수 있습니다.
오라클 내부 조인 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES, ORDERS WHERE EMPLOYEES.EMPLOYEE_ID = ORDERS.EMPLOYEE_ID; |
2) 외부 조인(Outer Join)
외부 조인은 조인 조건에서 동일한 값이 없더라도 행을 반환하는 조인입니다.
외부 조인은 왼쪽 테이블을 기준으로 외부 조인을 수행하는 Left Outer Join, 오른쪽 테이블을 기준으로 외부 조인을 수행하는 Right Outer Join, 양쪽 테이블을 기준으로 외부 조인을 수행하는 Full Outer Join이 있습니다.
(1) Left Outer Join
Left Outer Join은 왼쪽 테이블을 기준으로 외부 조인을 수행합니다.
Left Outer Join 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES LEFT OUTER JOIN ORDERS ON EMPLOYEES.EMPLOYEE_ID = ORDERS.EMPLOYEE_ID; |
결과는 다음과 같습니다.
Left Outer Join 결과
EMPLOYEE_ID |
FIRST_NAME |
LAST_NAME |
ORDER_DATE |
1 |
John |
Smith |
2023-01-01 |
2 |
Jane |
Doe |
2023-01-15 |
1 |
John |
Smith |
2023-02-01 |
4 |
Sarah |
Lee |
|
3 |
Bob |
Johnson |
|
오라클의 경우 다음과 같이 Left Outer Join 쿼리를 작성할 수 있습니다.
오라클 Left Outer Join 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES, ORDERS WHERE EMPLOYEES.EMPLOYEE_ID = ORDERS.EMPLOYEE_ID(+); |
(2) Right Outer Join
Right Outer Join은 오른쪽 테이블을 기준으로 외부 조인을 수행합니다.
Right Outer Join 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES RIGHT OUTER JOIN ORDERS ON EMPLOYEES.EMPLOYEE_ID = ORDERS.EMPLOYEE_ID; |
결과는 다음과 같습니다.
Right Outer Join 결과 EMPLOYEE_ID | FIRST_NAME | LAST_NAME | ORDER_DATE | 1 | John | Smith | 2023-01-01 | 1 | John | Smith | 2023-02-01 | 2 | Jane | Doe | 2023-01-15 |
|
|
| 2023-02-15 |
오라클의 경우 다음과 같이 Left Outer Join 쿼리를 작성할 수 있습니다.
오라클 Right Outer Join 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES, ORDERS WHERE EMPLOYEES.EMPLOYEE_ID(+) = ORDERS.EMPLOYEE_ID; |
(3) Full Outer Join
Full Outer Join은 오른쪽 테이블을 기준으로 외부 조인을 수행합니다.
Full Outer Join 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES FULL OUTER JOIN ORDERS ON EMPLOYEES.EMPLOYEE_ID = ORDERS.EMPLOYEE_ID; |
결과는 다음과 같습니다.
Full Outer Join 결과 EMPLOYEE_ID | FIRST_NAME | LAST_NAME | ORDER_DATE | 1 | John | Smith | 2023-01-01 | 2 | Jane | Doe | 2023-01-15 | 1 | John | Smith | 2023-02-01 |
|
|
| 2023-02-15 | 4 | Sarah | Lee |
| 3 | Bob | Johnson |
|
오라클의 경우 Full Outer Join 문법이 없습니다.
3) 크로스 조인(Cross Join)
크로스 조인은 조인 조건 없이 모든 데이터의 조합을 나타내는 조인입니다.
크로스 조인 문법
SELECT 컬럼명 FROM 테이블1 CROSS JOIN 테이블2; |
크로스 조인 예제
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES CROSS JOIN ORDERS; |
결과는 다음과 같습니다.
크로스 조인 결과 EMPLOYEE_ID | FIRST_NAME | LAST_NAME | ORDER_DATE | 1 | John
| Smith
| 2023-01-01
| 1 | John
| Smith
| 2023-01-15
| 1 | John | Smith | 2023-02-01
| 1 | John
| Smith
| 2023-02-15
| 2 | Jane | Doe | 2023-01-01 | 2 | Jane | Doe | 2023-01-15 | 2 | Jane
| Doe
| 2023-02-01 | 2 | Jane | Doe | 2023-02-15 | 3 | Bob | Johnson | 2023-01-01 | 3 | Bob | Johnson | 2023-01-15 | 3 | Bob
| Johnson
| 2023-02-01 | 3 | Bob | Johnson | 2023-02-15 | 4 | Sarah | Lee | 2023-01-01 | 4 | Sarah | Lee | 2023-01-15 | 4 | Sarah
| Lee
| 2023-02-01 | 4 | Sarah | Lee | 2023-02-15 |
4) 자연 조인(Natural Join)
자연 조인은 서로 다른 테이블에서 동일한 이름을 갖는 컬럼에 대하여 자동으로 동등 조인을 수행합니다.
자연 조인 문법
SELECT 컬럼명 FROM 테이블1 NATURAL JOIN 테이블2; |
자연 조인 예제
SELECT EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES NATURAL JOIN ORDERS; |
EMPLOYEES 테이블과 ORDERS 테이블에서 동일한 이름을 가지는 EMPLOYEE_ID 컬럼은 별명(Alias)를 주지 않았습니다. 이때 Natural Join을 사용하면 EMPLOYEE_ID 컬럼을 기준으로 내부 조인을 수행하게 됩니다.
결과는 다음과 같이 내부 조인의 결과와 같음을 확인할 수 있습니다.
자연 조인 결과 EMPLOYEE_ID | FIRST_NAME | LAST_NAME | ORDER_DATE | 1 | John | Smith | 2023-01-01 | 2 | Jane | Doe | 2023-01-15 | 1 | John | Smith | 2023-02-01
|
내부 조인에서도 ON 조건절 대신에 USING 조건절을 사용한다면 자연 조인처럼 별명(Alias) 없이 컬럼을 지정할 수 있습니다.
USING 조건절 예제
SELECT EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME, TO_CHAR(ORDERS.ORDER_DATE, 'YYYY-MM-DD') ORDER_DATE FROM EMPLOYEES INNER JOIN ORDERS USING (EMPLOYEE_ID); |
|