SELECT CategoryID, CategoryName, ( SELECTMAX(Price) FROM Products P WHERE P.CategoryID = C.CategoryID ) AS MaximumPrice, ( SELECTAVG(Price) FROM Products P WHERE P.CategoryID = C.CategoryID ) AS AveragePrice FROM Categories C;
SELECT ProductID, ProductName, CategoryID, Price -- ,(SELECT AVG(Price) FROM Products P2 -- WHERE P2.CategoryID = P1.CategoryID) FROM Products P1 WHERE Price < ( SELECTAVG(Price) FROM Products P2 WHERE P2.CategoryID = P1.CategoryID );
SELECT CategoryID, CategoryName -- ,(SELECT MAX(P.Price) FROM Products P -- WHERE P.CategoryID = C.CategoryID -- ) AS MaxPrice FROM Categories C WHEREEXISTS ( SELECT*FROM Products P WHERE P.CategoryID = C.CategoryID AND P.Price >80 );
2. JOIN - 여러 테이블 조립하기
2개 테이블을 연관 해서 가져온다. 구문이 JOIN, ON 들어간다. 제일 기본이 Inner Join이라고 하고 양쪽 모두에 값이 있는 행만 반환 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
SELECT C.CategoryID, C.CategoryName, P.ProductName FROM Categories C JOIN Products P ON C.CategoryID = P.CategoryID; -- ambiguous 주의!
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 ORDERBY ProductName;
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, 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 GROUPBY C.CategoryID, P.ProductID;
SELF JOIN 이라고 한개의 테이블로도 가능 하다
1 2 3 4 5 6 7 8
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번의 전, 마지막 번호의 다음은?
값이 없는 행을 가져 오고 싶을 때는 쓰는 것이 외부 조인이고 LEFT/RIGHT OUTER JOIN 왼쪽 NULL 값도 보여줄때 LEFT, 오른쪽 은 RIGHT 이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
SELECT C.CustomerName, S.SupplierName, C.City, C.Country FROM Customers C LEFTJOIN Suppliers S ON C.City = S.City AND C.Country = S.Country; -- LEFT를 RIGHT로 바꿔서도 실행해 볼 것
SELECT IFNULL(C.CustomerName, '-- NO CUSTOMER --'), IFNULL(S.SupplierName, '-- NO SUPPLIER --'), IFNULL(C.City, S.City), IFNULL(C.Country, S.Country) FROM Customers C LEFTJOIN Suppliers S ON C.City = S.City AND C.Country = S.Country;
SELECT CustomerName AS Name, City, Country, 'CUSTOMER' FROM Customers UNION SELECT SupplierName AS Name, City, Country, 'SUPPLIER' FROM Suppliers ORDERBY Name;
SELECT CategoryID AS ID FROM Categories WHERE CategoryID >4 UNION SELECT EmployeeID AS ID FROM Employees WHERE EmployeeID %2=0;
-- UNION ALL로 바꿔볼 것
교집합
1 2 3 4 5 6
SELECT CategoryID AS ID FROM Categories C, Employees E WHERE C.CategoryID >4 AND E.EmployeeID %2=0 AND C.CategoryID = E.EmployeeID;
차집합
1 2 3 4 5 6 7 8 9
SELECT CategoryID AS ID FROM Categories WHERE CategoryID >4 AND CategoryID NOTIN ( SELECT EmployeeID FROM Employees WHERE EmployeeID %2=0 );
대칭차집합: 교집합만 제외
1 2 3 4 5 6 7 8
SELECT ID FROM ( SELECT CategoryID AS ID FROM Categories WHERE CategoryID >4 UNIONALL SELECT EmployeeID AS ID FROM Employees WHERE EmployeeID %2=0 ) AS Temp GROUPBY ID HAVINGCOUNT(*) =1;