라즈베리파이반

라즈베리파이 등 컴퓨터계열 게시판입니다.

제목SQL: 조인(JOIN)2023-03-23 02:19
작성자user icon Level 4

88x31.png


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);


#SQL# JOIN# Inner JOIN# OUTER JOIN# CROSS JOIN# NATURAL JOIN
댓글
자동등록방지
(자동등록방지 숫자를 입력해 주세요)