1. GROUP BY - 조건에 따라 집계된 값을 가져옵니다.
→ 겹치지 않게 모두 가져올 수 있음
SELECT Country
FROM Customers
GROUP BY Country;
SELECT CategoryID
FROM Products
GROUP BY CategoryID;
💡 여러 컬럼을 기준으로 그룹화할 수도 있습니다.
SELECT
Country, City,
CONCAT_WS(', ', City, Country)
FROM Customers
GROUP BY Country, City;
📚 그룹 함수 활용하기
SELECT
COUNT(*), OrderDate
FROM Orders
GROUP BY OrderDate;
| COUNT(*) | OrderDate |
|---|---|
| 1 | 1996-07-04 |
| 1 | 1996-07-05 |
| 2 | 1996-07-08 |
SELECT
ProductID,
SUM(Quantity) AS QuantitySum
FROM OrderDetails
GROUP BY ProductID
ORDER BY QuantitySum DESC;
| ProductID | QuantitySum |
|---|---|
| 60 | 1577 |
| 59 | 1496 |
SELECT
CategoryID,
MAX(Price) AS MaxPrice,
MIN(Price) AS MinPrice,
TRUNCATE((MAX(Price) + MIN(Price)) / 2, 2) AS MedianPrice,
TRUNCATE(AVG(Price), 2) AS AveragePrice
FROM Products
GROUP BY CategoryID;
→ TRUNCATE(, 2) : 소수점 둘째자리까지 가능하도록
| CategoryID | MaxPrice | MinPrice | MedianPrice | AveragePrice |
|---|---|---|---|---|
| 1 | 263.50 | 4.50 | 134.00 | 37.97 |
| 2 | 43.90 | 10.00 | 26.95 | 23.06 |
| 3 | 81.00 | 9.20 | 45.10 | 25.16 |
SELECT
CONCAT_WS(', ', City, Country) AS Location,
COUNT(CustomerID)
FROM Customers
GROUP BY Country, City;
| Location | COUNT(CustomerID) |
|---|---|
| Buenos Aires, Argentina | 3 |
| Graz, Austria | 1 |
💡 WITH ROLLUP - 전체의 집계값, 총합
SELECT
Country, COUNT(*)
FROM Suppliers
GROUP BY Country
WITH ROLLUP;
| Country | COUNT(*) |
|---|---|
| Australia | 2 |
| Brazil | 1 |
💡 WHERE는 그룹하기 전 데이터, HAVING은 그룹 후 집계에 사용합니다.
→ 즉, HAVING은 그룹화를 한 다음에 걸러내는 것이고, WHERE은 그룹화하기 전에 미리 걸러내는 것!
⭐ NULL값은 집계하지 않습니다.
| 함수 | 설명 |
|---|---|
| MAX | 가장 큰 값 |
| MIN | 가장 작은 값 |
| COUNT | 갯수 (NULL값 제외) |
| SUM | 총합 |
| AVG | 평균 값 |
SELECT
Country, COUNT(*) AS Count
FROM Suppliers
GROUP BY Country
HAVING Count >= 3;
→ Country로 묶음!
| Country | Count |
|---|---|
| France | 3 |
| Germany | 3 |
| USA | 4 |
SELECT
COUNT(*) AS Count, OrderDate
FROM Orders
WHERE OrderDate > DATE('1996-12-31')
GROUP BY OrderDate
HAVING Count > 2;
| Count | OrderDate |
|---|---|
| 3 | 1997-12-16 |
| 3 | 1997-12-18 |
| 3 | 1997-12-22 |
SELECT
CategoryID,
MAX(Price) AS MaxPrice,
MIN(Price) AS MinPrice,
TRUNCATE((MAX(Price) + MIN(Price)) / 2, 2) AS MedianPrice,
TRUNCATE(AVG(Price), 2) AS AveragePrice
FROM Products
WHERE CategoryID > 2
GROUP BY CategoryID
HAVING
AveragePrice BETWEEN 20 AND 30
AND MedianPrice < 40;
| CategoryID | MaxPrice | MinPrice | MedianPrice | AveragePrice |
|---|---|---|---|---|
| 4 | 55.00 | 2.50 | 28.75 | 28.73 |
| 5 | 38.00 | 7.00 | 22.50 | 20.25 |
| 8 | 62.50 | 6.00 | 34.25 | 20.68 |
SELECT DISTINCT CategoryID
FROM Products;
-- 위의 GROUP BY를 사용한 쿼리와 결과 비교
| CategoryID |
|---|
| 1 |
| 2 |
| 7 |
SELECT COUNT DISTINCT CategoryID
FROM Products;
-- 오류 발생
SELECT DISTINCT Country
FROM Customers
ORDER BY Country;
→ ORDER BY로 수동으로 정렬가능!
Country
Argentina
Austria
Belgium
Brazil
Canada
💡 GROUP BY와 DISTINCT 함께 활용하기
SELECT
Country,
COUNT(DISTINCT CITY)
FROM Customers
GROUP BY Country;
| Country | COUNT(DISTINCT CITY) |
|---|---|
| Argentina | 1 |
| Austria | 2 |
| Belgium | 2 |