404 Brain Not Found

[database] SELECT JOIN 본문

DB 정리

[database] SELECT JOIN

했제 와 그랬제 2024. 9. 16. 16:48

 

관계형 데이터 베이스에서  관계를 맺고 있는 테이블의 데이터를 조회하기 위해서는 JOIN을 사용합니다.
A 와 B 테이블을 설계하였을때 A 와 B 두개의 테이블을 참조할 수 있는 Key가 존재한다면 두개의 테이블의 데이터를 합쳐서 출력할 수 있습니다. 이것이 관계형 데이터 베이스의 장점입니다.

이때 두개의 테이블의 데이터를 합칠수 있는 구문이 바로 JOIN입니다. 
관계가 있는 두개의 테이블을 하나로 합쳐서 표현할 수 있습니다.

JOIN 문법은 대표적으로 6개가 존재합니다.

주요 JOIN 유형

1. INNER JOIN: 두 테이블에서 조인 조건을 만족하는 행만 반환합니다.

SELECT * FROM Orders o
INNER JOIN Customers c ON o.CustomerID = c.CustomerID

 

2. LEFT (OUTER) JOIN: 왼쪽 테이블의 모든 행과 오른쪽 테이블에서 조건을 만족하는 행만  반환합니다. 조건을 만족하는 행이 오른쪽 테이블에 없으면 NULL로 채웁니다.

SELECT * FROM Customers c
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID

 

3. RIGHT (OUTER) JOIN: LEFT JOIN의 반대로, 오른쪽 테이블의 모든 행을 기준으로 합니다.

SELECT * FROM Orders o
RIGHT JOIN Customers c ON o.CustomerID = c.CustomerID

 

4. FULL (OUTER) JOIN: 양쪽 테이블의 모든 행을 반환합니다. 매칭되는 행이 없으면 NULL로 채웁니다.

SELECT * FROM Customers c
FULL OUTER JOIN Orders o ON c.CustomerID = o.CustomerID

 

5. CROSS JOIN: 두 테이블의 모든 가능한 조합을 반환합니다 (카테시안 곱).

SELECT * FROM Customers CROSS JOIN Products

 

6.SELF JOIN: 동일한 테이블을 자기 자신과 조인합니다.

SELECT e1.Name as Employee, e2.Name as Manager
FROM Employees e1
LEFT JOIN Employees e2 ON e1.ManagerID = e2.EmployeeID

 

7. NATURAL JOIN: 두 테이블에서 이름이 같은 모든 열을 기준으로 자동으로 조인합니다.

SELECT * FROM Customers NATURAL JOIN Orders

 

이렇게 다양한 JOIN 방법이 존재하지만 대부분의 경우는 LEFT JOIN 그리고 INNER JOIN을 사용합니다.
그렇기에 저는 LEFT JOIN, INNER JOIN, RIGHT JOIN 세가지만 다뤄보겠습니다.

 

예제

-- Orders 테이블 생성 및 데이터 삽입
CREATE TABLE Orders (
    OrderID INT PRIMARY KEY,
    CustomerName VARCHAR(100),
    OrderDate DATE,
    TotalAmount DECIMAL(10, 2)
);

INSERT INTO Orders (OrderID, CustomerName, OrderDate, TotalAmount) VALUES 
(1, '홍길동', '2023-09-01', 50000),
(2, '김철수', '2023-09-02', 75000),
(3, '이영희', '2023-09-03', 30000),
(4, '박지성', '2023-09-04', 100000),
(5, '최유나', '2023-09-05', 25000);  -- 이 주문은 OrderDetails에 없음

-- OrderDetails 테이블 생성 및 데이터 삽입
CREATE TABLE OrderDetails (
    OrderDetailID INT PRIMARY KEY,
    OrderID INT,
    ProductName VARCHAR(100),
    Quantity INT,
    UnitPrice DECIMAL(10, 2)
);

INSERT INTO OrderDetails (OrderDetailID, OrderID, ProductName, Quantity, UnitPrice) VALUES
(1, 1, '노트북', 1, 30000),
(2, 1, '마우스', 2, 10000),
(3, 2, '키보드', 1, 15000),
(4, 2, '모니터', 1, 60000),
(5, 3, '헤드폰', 1, 30000),
(6, 4, '스마트폰', 1, 80000),
(7, 4, '보호케이스', 1, 20000),
(8, 6, '태블릿', 1, 50000);  -- OrderID 6은 Orders 테이블에 없음

orders table 데이터

ordersdetails table 데이터

 

left outer join

left outer join의 경우는 왼쪽 테이블의 모든 행과 오른쪽 테이블에서 조건을 만족하는 행만 반환합니다. 만약에 조건을 만족하는 오른쪽 행이 없다면 NULL을 반환합니다.

-- 2. LEFT (OUTER) JOIN
SELECT o.OrderID, o.CustomerName, od.ProductName, od.Quantity, od.UnitPrice
FROM Orders o
LEFT JOIN OrderDetails od ON o.OrderID = od.OrderID;

 

현재 왼쪽 orders의 테이블을 기준으로 join을 하였기 떄문에 왼쪽에 있는 1,2,3,4,5 (홍길동, 김철수, 이영희, 박지성, 최유나)는 모두 반환됩니다. 하지만 오른쪽에 테이블에서 5번 최유나와 맵핑되는 행이 없기 때문에 NULL 값을 출력할 것 입니다. 

 

inner join

inner join의 경우는 왼쪽 테이블, 오른쪽 테이블 모두 존재하는 행들만 반환합니다. 즉 교집합 입니다.

-- 1. INNER JOIN
SELECT o.OrderID, o.CustomerName, od.ProductName, od.Quantity, od.UnitPrice
FROM Orders o
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID;

(order id 기준)
현재 왼쪽 orders 테이블은 1,2,3,4 ,5그리고 오른쪽 테이블 1,2,3,4,5,6 이렇게 두개가 존재합니다.
이떄 교집합은 1,2,3,4 입니다. (홍길동, 김철수, 이영희 박지성) 그렇기에 위의 쿼리를 실행하면 홍길동, 김철수, 이영희, 박지성 데이터만 출력되게 됩니다. 

right outer join

right outer join은 left outer join과 정확하게 반대입니다.

-- 3. RIGHT (OUTER) JOIN
SELECT o.OrderID, o.CustomerName, od.ProductName, od.Quantity, od.UnitPrice
FROM Orders o
RIGHT JOIN OrderDetails od ON o.OrderID = od.OrderID;

 

오른쪽 테이블을 기준으로 하기 때문에 오른쪽 테이블 모두 출력되고 오른쪽 행과 매칭되지 않는 왼쪽 테이블 행은 NULL로 출력됩니다.  현재 오른쪽 테이블은  1,2,3,4,5,6 이렇게 존재합니다. 이때 왼쪽 테이블은 6의 값이 없고 오른쪽 테이블은 최유나가 없기 때문에 홍길동,김철수.이영희,박지성,NULL이 출력됩니다.

 

'DB 정리' 카테고리의 다른 글

[database] UNION, UNION ALL  (3) 2024.09.16
[database] SELECT 쿼리 실행순서  (3) 2024.09.16