[SQL] 2-2. JOIN - 여러 테이블 조립하기

chxxrin·2024년 11월 21일
0

sql

목록 보기
4/5

1. JOIN(INNER JOIN) - 내부 조인

→ 나눈 테이블을 다시 합침!

  • 양쪽 모두에 값이 있는 행(NOT NULL) 반환
  • 'INNER '는 선택사항
SELECT * 
FROM Categories C
JOIN Products P 
  ON C.CategoryID = P.CategoryID; 
CategoryIDCategoryNameDescriptionProductIDProductNameSupplierIDCategoryIDUnitPrice
1BeveragesSoft drinks, coffees, teas, beers, and ales1Chais1110 boxes x 20 bags18.00
1BeveragesSoft drinks, coffees, teas, beers, and ales2Chang1124 - 12 oz bottles19.00
2CondimentsSweet and savory sauces, relishes, spreads, and seasonings3Aniseed Syrup1212 - 550 ml bottles10.00
SELECT C.CategoryID, C.CategoryName, P.ProductName
FROM Categories C
JOIN Products P 
  ON C.CategoryID = P.CategoryID; 

-- ambiguous 주의!
CategoryIDCategoryNameProductName
1BeveragesChais
1BeveragesChang
2CondimentsAniseed Syrup
SELECT
  CONCAT(
    P.ProductName, ' by ', S.SupplierName
  ) AS Product,
  S.Phone, P.Price
FROM Products P
JOIN Suppliers S
  ON P.SupplierID = S.SupplierID
WHERE Price > 50
ORDER BY ProductName;
ProductPhonePrice
Carnarvon Tigers by Pavlova, Ltd.(03) 444-234362.50
Côte de Blaye by Aux joyeux ecclésiastiques(1) 03.83.00.68263.50

💡 여러 테이블을 JOIN할 수 있습니다

SELECT 
  C.CategoryID, C.CategoryName, 
  P.ProductName, 
  O.OrderDate,
  D.Quantity
FROM Categories C

JOIN Products P 
  ON C.CategoryID = P.CategoryID
  
JOIN OrderDetails D
  ON P.ProductID = D.ProductID
  
JOIN Orders O
  ON O.OrderID = D.OrderID;
CategoryIDCategoryNameProductNameOrderDateQuantity
4Dairy ProductsQueso Cabrales1996-07-0412
5Grains/CerealsSingaporean Hokkien Fried Mee1996-07-0410

💡 JOIN한 테이블 GROUP하기

SELECT 
  C.CategoryName,
  MIN(O.OrderDate) AS FirstOrder,
  MAX(O.OrderDate) AS LastOrder,
  SUM(D.Quantity) AS TotalQuantity
FROM Categories C

JOIN Products P 
  ON C.CategoryID = P.CategoryID
  
JOIN OrderDetails D
  ON P.ProductID = D.ProductID
  
JOIN Orders O
  ON O.OrderID = D.OrderID
  
GROUP BY C.CategoryID;
CategoryNameFirstOrderLastOrderTotalQuantity
Beverages1996-07-101998-05-069532
Condiments1996-07-081998-05-065298
Confections1996-07-091998-05-067906
SELECT 
  C.CategoryName, P.ProductName,
  MIN(O.OrderDate) AS FirstOrder,
  MAX(O.OrderDate) AS LastOrder,
  SUM(D.Quantity) AS TotalQuantity
FROM Categories C
JOIN Products P 
  ON C.CategoryID = P.CategoryID
JOIN OrderDetails D
  ON P.ProductID = D.ProductID
JOIN Orders O
  ON O.OrderID = D.OrderID
GROUP BY C.CategoryID, P.ProductID;
CategoryNameProductNameFirstOrderLastOrderTotalQuantity
BeveragesChais1996-08-201998-05-05828
BeveragesChang1996-07-121998-05-061057
BeveragesGuaraná Fantástica1996-07-111998-05-051125

💡 SELF JOIN - 같은 테이블끼리

SELECT
  E1.EmployeeID, CONCAT_WS(' ', E1.FirstName, E1.LastName) AS Employee,
  E2.EmployeeID, CONCAT_WS(' ', E2.FirstName, E2.LastName) AS NextEmployee
FROM Employees E1 
JOIN Employees E2
ON E1.EmployeeID + 1 = E2.EmployeeID;

-- 1번의 전, 마지막 번호의 다음은? 알수없다. 왜냐하면 INNER JOIN은 NULL값은 가져오지 않으므로
EmployeeIDEmployeeEmployeeIDNextEmployee
1Nancy Davolio2Andrew Fuller
2Andrew Fuller3Janet Leverling
3Janet Leverling4Margaret Peacock

2. LEFT/RIGHT OUTER JOIN - 외부 조인

  • 반대쪽에 데이터가 있든 없든(NULL), 선택된 방향에 있으면 출력 - 행 수 결정
  • 'OUTER '는 선택사항
SELECT
  E1.EmployeeID, CONCAT_WS(' ', E1.FirstName, E1.LastName) AS Employee,
  E2.EmployeeID, CONCAT_WS(' ', E2.FirstName, E2.LastName) AS NextEmployee
FROM Employees E1
LEFT JOIN Employees E2
ON E1.EmployeeID + 1 = E2.EmployeeID
ORDER BY E1.EmployeeID;

-- LEFT를 RIGHT로 바꿔서도 실행해 볼 것
7Robert King8Laura Callahan
8Laura Callahan9Anne Dodsworth
9Anne Dodsworth

LEFT JOIN 을 하면 조인하는 곳이 NULL 이더라도 데이터를 가져옴

SELECT
  E1.EmployeeID, CONCAT_WS(' ', E1.FirstName, E1.LastName) AS Employee,
  E2.EmployeeID, CONCAT_WS(' ', E2.FirstName, E2.LastName) AS NextEmployee
FROM Employees E1
RIGHT JOIN Employees E2
ON E1.EmployeeID + 1 = E2.EmployeeID
ORDER BY E1.EmployeeID;

-- LEFT를 RIGHT로 바꿔서도 실행해 볼 것
EmployeeIDEmployeeEmployeeIDNextEmployee
1Nancy Davolio
1Nancy Davolio2Andrew Fuller
2Andrew Fuller3Janet Leverling

→ RIGHT JOIN 을 하면 조인하는 곳이 NULL 이더라도 데이터를 가져옴

  • LEFT JOINE1을 기준으로,
  • RIGHT JOINE2을 기준으로 조인을 수행하여, 조인 기준에 맞지 않는 경우 NULL 값을 반환하게 됩니다.
SELECT
  C.CustomerName, S.SupplierName,
  C.City, C.Country
FROM Customers C
LEFT JOIN Suppliers S
ON C.City = S.City AND C.Country = S.Country;

-- LEFT를 RIGHT로 바꿔서도 실행해 볼 것
Mère PaillardeMa MaisonMontréalCanada
Ana Trujillo Emparedados y heladosMéxico D.F.Mexico
Antonio Moreno TaqueríaMéxico D.F.Mexico
SELECT
  C.CustomerName, S.SupplierName,
  C.City, C.Country
FROM Customers C
RIGHT JOIN Suppliers S
ON C.City = S.City AND C.Country = S.Country;

-- LEFT를 RIGHT로 바꿔서도 실행해 볼 것
Tradição HipermercadosRefrescos Americanas LTDASão PauloBrazil
Exotic Liquid
New Orleans Cajun Delights
SELECT
  IFNULL(C.CustomerName, '-- NO CUSTOMER --'),
  IFNULL(S.SupplierName, '-- NO SUPPLIER --'),
  IFNULL(C.City, S.City),
  IFNULL(C.Country, S.Country)
FROM Customers C
LEFT JOIN Suppliers S
ON C.City = S.City AND C.Country = S.Country;

-- LEFT를 RIGHT로 바꿔서도 실행해 볼 것
Mère PaillardeMa MaisonMontréalCanada
Ana Trujillo Emparedados y helados-- NO SUPPLIER --México D.F.Mexico
Antonio Moreno Taquería-- NO SUPPLIER --México D.F.
SELECT
  IFNULL(C.CustomerName, '-- NO CUSTOMER --'),
  IFNULL(S.SupplierName, '-- NO SUPPLIER --'),
  IFNULL(C.City, S.City),
  IFNULL(C.Country, S.Country)
FROM Customers C
RIGHT JOIN Suppliers S
ON C.City = S.City AND C.Country = S.Country;

-- LEFT를 RIGHT로 바꿔서도 실행해 볼 것
Tradição HipermercadosRefrescos Americanas LTDASão PauloBrazil
-- NO CUSTOMER --Exotic LiquidLondonaUK
-- NO CUSTOMER --New Orleans Cajun DelightsNew OrleansUS

왼쪽, 오른쪽 JOIN해서 NULL값 포함 모두 출력하려면

  1. LEFT JOIN
  2. RIGHT JOIN
  3. UNION
SELECT
  IFNULL(C.CustomerName, '-- NO CUSTOMER --') AS CustomerName,
  IFNULL(S.SupplierName, '-- NO SUPPLIER --') AS SupplierName,
  IFNULL(C.City, S.City) AS City,
  IFNULL(C.Country, S.Country) AS Country
FROM Customers C
LEFT JOIN Suppliers S
ON C.City = S.City AND C.Country = S.Country

UNION

SELECT
  IFNULL(C.CustomerName, '-- NO CUSTOMER --') AS CustomerName,
  IFNULL(S.SupplierName, '-- NO SUPPLIER --') AS SupplierName,
  IFNULL(C.City, S.City) AS City,
  IFNULL(C.Country, S.Country) AS Country
FROM Customers C
RIGHT JOIN Suppliers S
ON C.City = S.City AND C.Country = S.Country;
  • UNION중복을 제거하여 결과 집합의 고유한 행만 반환합니다.
  • UNION ALL모든 행을 반환하여 중복을 허용합니다.

3. CROSS JOIN - 교차 조인

  • 조건 없이 모든 조합 반환(A * B)
  • 이것저것 모든 조합을 확인해보고 싶을 때 사용 !!
SELECT
  E1.LastName, E2.FirstName
FROM Employees E1
CROSS JOIN Employees E2
ORDER BY E1.EmployeeID;
LastNameFirstName
DavolioMichael
DavolioJanet
DavolioRobert

0개의 댓글

관련 채용 정보