개발공부/SQL

[SQL] JOIN

jnnjnn 2024. 4. 30. 17:46

 

JOIN

여러 테이블을 묶어서 조회할 때 사용합니다

두 개 이상의 테이블을 결합시킵니다

 

cartesian product

CROSS JOIN으로 두 테이블의 모든 행을 조인합니다

컬럼수는 두 테이블의 컬럼 수의 합, 행(레코드) 수는 두 테이블 행의 수의 곱이 됩니다

 

SELECT *
FROM table1
         JOIN table2;

 

 

 

INNER JOIN

두 테이블에 모두 있는 값만 출력합니다

SELECT *
FROM table1
         JOIN table2 ON col1 = col2;

 

 

 

LEFT OUTER JOIN

INNER JOIN 값과 왼쪽 테이블의 모든 값을 출력합니다

OUTER는 생략 가능합니다

SELECT *
FROM table1
         LEFT OUTER JOIN table2 ON col1 = col2;

SELECT *
FROM table1
         LEFT JOIN table2 ON col1 = col2;

 

 

 

 

RIGHT OUTER JOIN

INNER JOIN값과 오른쪽 테이블의 모든 값을 출력합니다

역시 OUTER는 생략 가능합니다

 

SELECT *
FROM table3
         RIGHT OUTER JOIN table4 ON col1 = col2;

SELECT *
FROM table3
         RIGHT JOIN table4 ON col1 = col2;

 

 

 

FULL OUTER JOIN

양쪽 테이블의 값을 모두 출력합니다.

mariadb에서는 FULL OUTER JOIN을 지원하지 않아 UNION을 사용합니다

UNION은 중복이 제거된 값을, UNION ALL은 중복이 제거되지 않은 값을 출력합니다

# UNION (중복 제거됨)

SELECT *
FROM table11
         LEFT JOIN table10
                   ON col1 = col_a

UNION

SELECT *
FROM table10
         LEFT JOIN table11
                   ON col1 = col_a;


#UNION ALL (중복제거 x)

SELECT *
FROM table11
         LEFT JOIN table10
                   ON col1 = col_a

UNION ALL

SELECT *
FROM table10
         LEFT JOIN table11
                   ON col1 = col_a;

 

 

OUTER JOIN 활용 예제

OUTER JOIN은 존재하지 않는 데이터를 NULL으로 출력하기 때문에 한쪽에만 존재하는 데이터만 출력할 수 있습니

# 상품이 존재하지 않는 카테고리를 알 수 있음
SELECT *
FROM category c
         LEFT JOIN product p ON c.id = p.category_id
WHERE p.id IS NULL;

 

 

 

 

 

SELF JOIN

자기 자신을 조인합니다

CREATE TABLE employee
(
    id         INT PRIMARY KEY,
    name       VARCHAR(10) NOT NULL,
    info       VARCHAR(10) NOT NULL,
    manager_id INT
);

INSERT INTO employee
VALUES (1, '손흥민', '과장', 6),
       (2, '이강인', '대리', 1),
       (3, '이정후', '사원', 1),
       (4, '황희찬', '대리', 1),
       (5, '차범근', '사장', null),
       (6, '박지성', '차장', 5);

# 손흥민의 직속 상사는?
SELECT m.name
FROM employee e
         JOIN employee m
              ON e.manager_id = m.id
WHERE e.name = '손흥민';

# 이정후의 직속 상사는?
SELECT e2.name
FROM employee e1
         JOIN employee e2 ON e1.manager_id = e2.id
WHERE e1.name = '이정후';

# 손흥민의 직속 부하는?
SELECT e2.name
FROM employee e1
         JOIN employee e2 ON e1.id = e2.manager_id
WHERE e1.name = '손흥민'

 

매니저 번호(manager_id)와 사원번호(id)를 조인하여 해당 직원의 직속 상사를 알아낼 수 있습니다

 

 

다중 JOIN

여러 개의 테이블을 조인하여 원하는 결과를 출력할 수 있습니다

# Fløtemysost 상품을 구매한 고객의 이름과 주소, 주문일 조회
SELECT DISTINCT c.CustomerName, c.Address, o.OrderDate
FROM Customers c
         JOIN Orders o ON c.CustomerID = o.CustomerID
         JOIN OrderDetails od ON od.OrderID = o.OrderID
         JOIN Products p ON od.ProductID = p.ProductID
WHERE ProductName = 'Fløtemysost'
ORDER BY c.CustomerName, c.Address, o.OrderDate;