제16장 GROUP BY - 같은 종류끼리 묶어서 계산하기
오늘의 질문
사장님이 고객 목록을 보다가 말했습니다.
"고객은 모두 몇 명입니까?"
이 질문은 지난 시간에 배운 COUNT()로 해결할 수 있습니다.
하지만 이번에는 이렇게 질문합니다.
"국가별 고객 수를 알고 싶습니다."
그리고 상품 담당자는 이렇게 요청합니다.
"카테고리별 평균 가격도 계산해 주세요."
이제는 전체를 하나로 계산하는 것이 아니라, 같은 종류끼리 묶어서 계산해야 합니다.
이럴 때 사용하는 명령어가 바로 GROUP BY입니다.
학습 목표
이번 장을 학습하면 다음 내용을 할 수 있습니다.
- GROUP BY의 역할을 설명할 수 있다.
- 같은 값을 가진 데이터를 그룹으로 묶을 수 있다.
- GROUP BY와 집계 함수를 함께 사용할 수 있다.
- 실무에서 GROUP BY를 활용할 수 있다.
16-1. GROUP BY란 무엇일까요?
생각해 봅시다.
다음과 같은 고객 정보가 있습니다.
| 고객 | 국가 |
| Alfreds | Germany |
| Around the Horn | UK |
| Bon app' | France |
| Blauer See | Germany |
| B's Beverages | UK |
이 데이터를
Germany
Germany
UK
UK
France
처럼 같은 나라끼리 모은 다음
각 나라의 고객 수를 계산하는 것이
GROUP BY의 역할입니다.
즉,
같은 값을 가진 행을 하나의 그룹으로 묶습니다.
🤔 왜 GROUP BY가 필요할까요?
지난 시간에는
SELECT COUNT(*)
FROM Customers;
를 사용했습니다.
결과
91
하지만 회사에서는
Germany : 11명
France : 9명
UK : 7명
처럼 보고 싶어 합니다.
이것이 GROUP BY가 필요한 이유입니다.
16-2. 먼저 실행해 봅시다.
SELECT Country,
COUNT(*)
FROM Customers
GROUP BY Country;
실행 결과(예)
| Country | COUNT(*) |
| Germany | 11 |
| France | 9 |
| UK | 7 |
| Brazil | 9 |
같은 국가끼리 묶은 뒤
고객 수를 계산했습니다.
잠깐 생각해 보기
다음 SQL과 무엇이 다를까요?
SELECT COUNT(*)
FROM Customers;
↓
전체 고객 수
SELECT Country,
COUNT(*)
FROM Customers
GROUP BY Country;
↓
국가별 고객 수
GROUP BY 하나만 추가했는데
결과가 완전히 달라졌습니다.
16-3. SQL을 한 줄씩 읽어 보기
SELECT Country,
COUNT(*)
FROM Customers
GROUP BY Country;
SELECT Country
↓
국가를 표시하고
COUNT(*)
↓
각 그룹의 고객 수를 계산하며
FROM Customers
↓
Customers 테이블에서
GROUP BY Country
↓
같은 국가끼리 묶습니다.
즉,
국가별 고객 수를 계산하라.
라는 의미입니다.
🤔 GROUP BY는 언제 사용할까요?
회사에서는
전체보다
"분류별"
통계를 더 많이 봅니다.
예를 들면
- 국가별 고객 수
- 직원별 주문 수
- 카테고리별 상품 수
- 연도별 주문 수
등입니다.
16-4. 평균도 계산할 수 있습니다.
SELECT CategoryID,
AVG(Price)
FROM Products
GROUP BY CategoryID;
카테고리별 평균 가격을 계산합니다.
16-5. 여러 개의 집계 함수 사용하기
SELECT CategoryID,
COUNT(*),
AVG(Price),
MIN(Price),
MAX(Price)
FROM Products
GROUP BY CategoryID;
실무에서는
이처럼 여러 집계 함수를 함께 사용하는 경우가 매우 많습니다.
💡 잠깐! 이것도 알아두세요
GROUP BY는
집계 함수와 함께 사용하는 경우가 대부분입니다.
예를 들어
- COUNT()
- SUM()
- AVG()
- MIN()
- MAX()
등과 함께 자주 사용됩니다.
자주 하는 실수
① GROUP BY 없이 Country를 SELECT한다.
잘못된 예
SELECT Country,
COUNT(*)
FROM Customers;
왜 잘못일까요?
Country는 여러 개의 값이 있는데
COUNT(*)는 하나의 값만 반환합니다.
어떤 Country를 출력해야 하는지 SQL이 결정할 수 없기 때문입니다.
② GROUP BY와 ORDER BY를 혼동한다.
GROUP BY
↓
묶는다.
ORDER BY
↓
정렬한다.
③ 그룹을 만든 뒤 집계 함수를 사용하지 않는다.
GROUP BY는
대부분 집계 함수와 함께 사용합니다.
④ GROUP BY가 데이터를 정렬한다고 생각한다.
GROUP BY는
묶는 기능입니다.
정렬은 ORDER BY입니다.
(MySQL에서는 결과가 정렬된 것처럼 보일 수 있지만, 이는 보장되지 않습니다.)
실무에서는 어떻게 사용할까요?
회사에서는 GROUP BY를 이용하여
- 국가별 고객 수
- 월별 주문 건수
- 직원별 매출
- 카테고리별 평균 가격
- 지역별 판매량
등의 통계 자료를 만듭니다.
대부분의 경영 보고서에서 사용됩니다.
실습
실습 1
국가별 고객 수를 조회하세요.
SELECT Country,
COUNT(*)
FROM Customers
GROUP BY Country;
실습 2
카테고리별 상품 개수를 조회하세요.
SELECT CategoryID,
COUNT(*)
FROM Products
GROUP BY CategoryID;
실습 3
카테고리별 평균 가격을 조회하세요.
SELECT CategoryID,
AVG(Price)
FROM Products
GROUP BY CategoryID;
실무 미션
당신은 영업관리팀 직원입니다.
팀장님이
국가별 고객 현황 보고서를 요청했습니다.
다음 항목을 출력하세요.
- Country
- 고객 수
- 고객 수가 많은 순으로 정렬
힌트)
COUNT()와 ORDER BY를 함께 사용할 수 있습니다.
핵심 정리
✔ GROUP BY는 같은 값을 가진 행을 하나의 그룹으로 묶는다.
✔ 그룹마다 집계 함수를 계산한다.
✔ COUNT(), SUM(), AVG(), MIN(), MAX()와 자주 함께 사용한다.
✔ GROUP BY는 묶기, ORDER BY는 정렬하기이다.
"WHERE와 HAVING의 차이"를 교실로 비유하기
학생이 30명 있는 학급을 생각해 봅시다.
- WHERE는 학생을 모둠으로 나누기 전에 조건에 맞는 학생만 먼저 선택하는 것입니다.
- 예) "남학생만 앞으로 나오세요."
- GROUP BY는 선택된 학생들을 반별, 동아리별 등으로 모둠을 만드는 과정입니다.
- HAVING은 모둠이 만들어진 뒤 그 모둠을 대상으로 다시 선택하는 것입니다.
- 예) "인원이 5명 이상인 모둠만 발표하세요."
연습 문제
기본 문제
- GROUP BY는 어떤 역할을 하나요?
- GROUP BY와 ORDER BY의 차이를 설명해 보세요.
- 국가별 고객 수를 계산하려면 어떤 집계 함수를 사용해야 하나요?
응용 문제
- Products 테이블에서 CategoryID별 상품 개수를 구하는 SQL을 작성하세요.
- Products 테이블에서 CategoryID별 최고 가격을 구하는 SQL을 작성하세요.
- Orders 테이블에서 EmployeeID별 주문 건수를 구하는 SQL을 작성하세요.
도전 문제
Orders 테이블에서
직원별로
- 주문 건수
- 가장 빠른 주문일
- 가장 늦은 주문일
을 한 번의 SQL로 출력해 보세요.
다음 장 예고
이번 장에서는 GROUP BY를 이용하여 같은 종류의 데이터를 묶고 통계를 계산하는 방법을 배웠습니다.
하지만 보고서를 만들다 보면 다음과 같은 요청을 받을 수 있습니다.
"고객이 5명 이상인 국가만 보여 주세요."
"평균 가격이 30달러 이상인 카테고리만 출력해 주세요."
이처럼 그룹을 만든 후 특정 조건을 만족하는 그룹만 선택할 때 사용하는 명령어가 바로 HAVING입니다.
다음 장에서는 WHERE와 HAVING의 차이를 이해하고, 원하는 그룹만 골라내는 방법을 배우겠습니다.
'프로그래밍 > MySQL' 카테고리의 다른 글
| 📊 [SQL 프로젝트] 제18장 GROUP BY와 SUM - 그룹별 합계 계산하기 (0) | 2026.07.01 |
|---|---|
| 📊 [SQL 프로젝트] 제17장 HAVING - 그룹을 만든 후 조건 선택하기 (0) | 2026.07.01 |
| 📊 [SQL 프로젝트] 제15장 집계 함수(Aggregate Functions) - 여러 행을 한 번에 계산하기 (0) | 2026.06.30 |
| 📊 [SQL 프로젝트] 제14장 날짜 함수(Date Functions) - 날짜와 시간을 자유롭게 다루기 (0) | 2026.06.30 |
| 📊 [SQL 프로젝트] 제13장 숫자 함수(Numeric Functions) - 숫자를 계산하고 원하는 형태로 바꾸기 (0) | 2026.06.29 |