본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

MySQL GROUP BY · 집계함수 · AS 완전 정리

by 왕진 2026. 7. 14.
반응형

 

 

Web Development · MySQL

MySQL GROUP BY · 집계함수 · AS —
그룹화와 집계 완전 정리

GROUP BY · SUM · AVG · COUNT · MAX · MIN · HAVING · AS 별칭
시작 오늘 분석할 코드
-- 회원별 구매 수량 합계 SELECT userID, SUM(amount) FROM buytbl GROUP BY userID; -- AS로 컬럼명을 읽기 쉽게 SELECT userID AS '사용자 아이디', SUM(amount) AS '총 구매 개수' FROM buytbl GROUP BY userID; -- price*amount = 구매금액, 회원별 총 구매액 SELECT userID AS '사용자 아이디', SUM(price*amount) AS '총 구매액' FROM buytbl GROUP BY userID; -- 전체 평균 구매 개수 (GROUP BY 없음 = 전체 대상) SELECT AVG(amount) AS '평균 구매 개수' FROM buytbl; -- 회원별 평균 구매 개수 SELECT userID, AVG(amount) AS '평균 구매 개수' FROM buytbl GROUP BY userID;
GROUP BY는 "회원별, 지역별, 상품별"처럼 특정 컬럼 값이 같은 행들을 묶는다. 묶인 그룹마다 집계함수(SUM, AVG...)가 적용되어 그룹당 1개의 결과가 나온다.

1 GROUP BY 개념

GROUP BY 없이 SUM(amount)을 쓰면 전체 행의 합계를 하나 돌려준다. GROUP BY userID를 추가하면 userID 값이 같은 행들끼리 묶어서 각 그룹의 합계를 반환한다.

-- GROUP BY 없음: 전체 12건의 총 구매 개수 합계 = 1개 행 SELECT SUM(amount) FROM buytbl; -- 결과: 1행 (전체 합계) -- GROUP BY userID: 회원별 그룹으로 묶어 각 그룹의 합계 SELECT userID, SUM(amount) FROM buytbl GROUP BY userID; -- 결과: 회원 수만큼의 행 (회원별 합계)
userID SUM(amount) 설명
BBK 4 BBK 회원의 구매건 수량 합계
EJW 4 EJW 회원의 구매건 수량 합계
JYP 3 JYP 회원의 구매건 수량 합계
KBS 7 KBS 회원의 구매건 수량 합계
SSK 5 SSK 회원의 구매건 수량 합계

2 집계함수 5종
SUM(컬럼)
그룹 내 합계. NULL은 무시됨. SUM(price*amount)처럼 식도 가능
AVG(컬럼)
그룹 내 평균. NULL인 행은 분모에서 제외됨
COUNT(컬럼)
NULL이 아닌 행의 개수. COUNT(*)는 전체 행 수
MAX(컬럼)
그룹 내 최댓값. 숫자·날짜·문자 모두 가능
MIN(컬럼)
그룹 내 최솟값. 날짜의 경우 가장 이른 날짜
-- 집계함수 5종 한 번에 확인 SELECT COUNT(*) AS '총 구매건수', SUM(amount) AS '총 수량', AVG(amount) AS '평균 수량', MAX(price) AS '최고 단가', MIN(price) AS '최저 단가' FROM buytbl; -- 회원별 통계 SELECT userID, COUNT(*) AS '구매건수', SUM(price*amount) AS '총 구매액' FROM buytbl GROUP BY userID;
집계함수(SUM, AVG, COUNT...)는 WHERE 절에서 사용할 수 없다. WHERE는 GROUP BY 이전에 실행되어 집계 결과가 아직 없기 때문이다. → 그룹 결과 필터는 HAVING 사용

3 AS — 별칭 (Alias)

컬럼명이나 집계식에 AS '보기 좋은 이름'을 붙이면 결과 헤더가 바뀐다. 한글·공백 포함 시 작은따옴표로 감싼다.

-- AS 없이: 컬럼 헤더가 SUM(amount) 그대로 표시 SELECT userID, SUM(amount) FROM buytbl GROUP BY userID; -- AS 적용: 헤더가 '총 구매 개수'로 바뀜 SELECT userID AS '사용자 아이디', SUM(amount) AS '총 구매 개수' FROM buytbl GROUP BY userID; -- AS를 ORDER BY에서 참조 가능 (SELECT 이후 실행되므로) SELECT userID, SUM(price*amount) AS 총구매액 FROM buytbl GROUP BY userID ORDER BY 총구매액 DESC;
AS 규칙 설명
한글/공백 없음 AS 이름 (따옴표 생략 가능)
한글/공백 포함 AS '사용자 아이디' (작은따옴표 필수)
ORDER BY에서 참조 가능 (SELECT 이후 실행)
WHERE에서 참조 불가 (WHERE는 SELECT 이전 실행)
GROUP BY에서 참조 MySQL에서는 가능 (표준 SQL과 다름)

 

반응형

 

4 HAVING — 그룹 결과 필터

WHERE는 행 단위 필터, HAVING은 그룹 단위 필터다. 집계 결과(SUM, COUNT...)에 조건을 걸 때는 반드시 HAVING을 사용한다.

-- 총 구매액이 1000 이상인 회원만 SELECT userID, SUM(price*amount) AS 총구매액 FROM buytbl GROUP BY userID HAVING SUM(price*amount) >= 1000; -- 구매 건수가 3건 이상인 회원만 SELECT userID, COUNT(*) AS 구매건수 FROM buytbl GROUP BY userID HAVING COUNT(*) >= 3; -- WHERE(행 필터) + GROUP BY + HAVING(그룹 필터) 조합 SELECT userID, SUM(price*amount) AS 총구매액 FROM buytbl WHERE prodName != '모니터' GROUP BY userID HAVING SUM(price*amount) >= 500;
구분 WHERE HAVING
적용 대상 개별 행 그룹 결과
실행 시점 GROUP BY 이전 GROUP BY 이후
집계함수 사용 불가 가능 (필수)
예시 WHERE price > 100 HAVING SUM(amount) > 5

5 GROUP BY + ORDER BY 조합

GROUP BY로 그룹화한 결과를 ORDER BY로 정렬해서 원하는 순서로 출력한다. 실무에서 가장 자주 쓰는 패턴이다.

-- 총 구매액 많은 순으로 회원 랭킹 SELECT userID AS '회원', COUNT(*) AS '구매건수', SUM(amount) AS '총수량', SUM(price*amount) AS '총구매액' FROM buytbl GROUP BY userID ORDER BY 총구매액 DESC; -- 복합 GROUP BY (그룹명 + 상품명 단위) SELECT groupName, prodName, SUM(price*amount) AS '그룹상품별 총액' FROM buytbl GROUP BY groupName, prodName ORDER BY groupName, 그룹상품별 총액 DESC;
ORDER BY에서 AS 별칭을 그대로 쓸 수 있다 — ORDER BY는 SELECT 이후에 실행되므로 별칭이 이미 만들어져 있다. WHERE에서는 불가.

6 자주 하는 실수
실수 증상 해결
WHERE에 SUM() 사용 Invalid use of group function HAVING SUM() >= N 으로 변경
GROUP BY 없이 집계+비집계 혼용 예상 밖 결과 or 오류 집계하려는 컬럼 외는 GROUP BY에 포함
AS 별칭을 WHERE에서 참조 Unknown column 오류 WHERE는 SELECT 이전 실행 — 원래 식 사용
COUNT(*) vs COUNT(컬럼) NULL 행 포함 여부 차이 COUNT(*)=전체 행, COUNT(col)=NULL 제외
GROUP BY 컬럼 미포함 Syntax error or 비결정적 결과 SELECT에서 집계 안 된 컬럼은 GROUP BY에 포함

핵심 한 줄 요약

GROUP BY 컬럼같은 컬럼값을 가진 행들을 묶어 그룹 만들기
SUM(price*amount)그룹별 총 구매액 — 식 안에 연산도 가능
AVG(amount)그룹별 평균 — NULL인 행은 분모에서 제외
COUNT(*)전체 행 수 / COUNT(col)은 NULL 제외 행 수
MAX / MIN(컬럼)그룹 내 최댓값/최솟값 — 날짜·문자도 가능
AS '별칭'결과 헤더 이름 변경 — 한글·공백은 따옴표 필요
HAVING 조건GROUP BY 결과 필터 — WHERE는 행 필터, HAVING은 그룹 필터
WHERE + GROUP BY + HAVING행 필터 → 그룹화 → 그룹 필터 순 실행
ORDER BY 별칭GROUP BY 결과를 AS 별칭으로 정렬 가능
집계함수 WHERE 불가WHERE 절에서는 집계함수 사용 불가 → HAVING 사용
실무 패턴GROUP BY + SUM + ORDER BY DESC = 인기 회원/상품 랭킹
복합 GROUP BYGROUP BY A, B = A+B 조합 단위로 그룹화
집계 + WHEREWHERE로 먼저 행 줄이기 → GROUP BY 집계 성능 향상
NULL 집계SUM/AVG에서 NULL 행은 무시 — COUNT(*)는 NULL 포함
GROUP BY 없는 집계전체 테이블을 하나의 그룹으로 — 결과 1행만 반환
ROUND 활용ROUND(AVG(amount), 1) = 소수점 1자리로 반올림
GROUP BY 실행 순서FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
SUM vs COUNTSUM = 값의 합계, COUNT = 행의 개수 — 혼동 주의
HAVING vs WHERE집계 조건은 HAVING, 행 필터는 WHERE — WHERE가 더 빠름
GROUP BY 순서GROUP BY만으로는 순서 보장 없음 — 항상 ORDER BY와 함께
집계 전 필터WHERE로 먼저 불필요한 행 제거 후 GROUP BY — 성능 유리
집계 후 필터그룹 결과 기준 필터 — HAVING SUM(price*amount) >= 1000
GROUP BY + LIMITGROUP BY 결과 중 상위 N개만 — ORDER BY와 함께 사용
MIN/MAX 날짜MAX(mDate) = 가장 최근 가입일, MIN(mDate) = 가장 오래된 가입일
SUM(0) vs NULLSUM이 NULL 반환 = 그룹에 행이 없음. 0과 NULL은 다름

Tags

#MySQL #GROUP BY #SUM #AVG #COUNT #HAVING #집계함수 #AS #SQL #데이터베이스 #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
MySQL, GROUP BY, SUM, AVG, COUNT, HAVING, 집계함수, AS, SQL, 데이터베이스, 웹개발, 티스토리
반응형

댓글