Sub Query
비상관 서브쿼리
- 본 쿼리에 독립적인 서브쿼리문
ALL
: 서브쿼리의 모든 결과에 대해 적용
ANY
: 서브쿼리의 하나 이상의 결과에 대해 적용
SELECT * FROM Products
WHERE Price < (
SELECT AVG(Price) FROM Products
);
SELECT
CategoryID, CategoryName, Description
FROM Categories
WHERE
CategoryID IN
(SELECT CategoryID FROM Products
WHERE Price > 50);
SELECT * FROM Products
WHERE Price > ALL (
SELECT Price FROM Products
WHERE CategoryID = 2
);
SELECT
CategoryID, CategoryName, Description
FROM Categories
WHERE
CategoryID = ANY
(SELECT CategoryID FROM Products
WHERE Price > 50);
상관 서브쿼리
- 본 쿼리에 의존하는 서브쿼리문
EXISTS/ NOT EXISTS
: 서브쿼리의 결과에 데이터가 존재하는지 여부
SELECT
ProductID, ProductName,
(
SELECT CategoryName FROM Categories C
WHERE C.CategoryID = P.CategoryID
) AS CategoryName
FROM Products P;
SELECT
SupplierName, Country, City,
(
SELECT COUNT(*) FROM Customers C
WHERE C.Country = S.Country
) AS CustomersInTheCountry,
(
SELECT COUNT(*) FROM Customers C
WHERE C.Country = S.Country
AND C.City = S.City
) AS CustomersInTheCity
FROM Suppliers S;
SELECT
ProductID, ProductName, CategoryID, Price
,(SELECT AVG(Price) FROM Products P2
WHERE P2.CategoryID = P1.CategoryID)
FROM Products P1
WHERE Price < (
SELECT AVG(Price) FROM Products P2
WHERE P2.CategoryID = P1.CategoryID
);
SELECT
CategoryID, CategoryName
FROM Categories C
WHERE EXISTS (
SELECT * FROM Products P
WHERE P.CategoryID = C.CategoryID
AND P.Price > 80
);
JOIN
- 테이블 합치기
- 기본적으로 내부(INNER) JOIN : 양쪽 모두 값이 있는 행만 반환
SELECT * FROM Categories C
JOIN Products P
ON C.CategoryID = P.CategoryID;
SELECT CategoryID, C.CategoryName, P.ProductName
FROM Categories C
JOIN Products P
ON C.CategoryID = P.CategoryID;
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;
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;
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;
LEFT/RIGHT JOIN
- 외부(OUTER) JOIN : 한쪽만 값이 있어도 반환
LEFT JOIN
: 오른쪽 값이 없어도 가져옴
RIGHT JOIN
: 왼쪽 값이 없어도 가져옴
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;
CustomerName | SupplierName |
---|
A | A' |
B | B' |
... | ... |
F | F' |
G | NULL |
CustomerName | SupplierName |
---|
A | A' |
B | B' |
... | ... |
F | F' |
NULL | G' |
CROSS JOIN
SELECT
E1.LastName, E2.FirstName
FROM Employees E1
CROSS JOIN Employees E2
ORDER BY E1.EmployeeID;
UNION
- 서로다른 테이블, column들을 같은 column으로 이어서 보여줌
UNION
: 중복을 제거한 집합
UNION ALL
: 중복을 포함한 집합
SELECT CustomerName AS Name, City, Country, 'CUSTOMER'
FROM Customers
UNION
SELECT SupplierName AS Name, City, Country, 'SUPPLIER'
FROM Suppliers
ORDER BY Name;
참고자료