COUNT, SUM, AVG 같은 집계 함수는 전체 데이터를 하나로 요약한다. 그런데 "전체 주문 수"가 아니라 "회원별 주문 수"가 필요하다면? 데이터를 특정 기준으로 묶어서 각 그룹마다 집계해야 한다. 이때 쓰는 게 GROUP BY다.
SELECT member_id, COUNT(*) AS 주문횟수
FROM orders
GROUP BY member_id;
member_id | 주문횟수
----------+--------
1 | 3
2 | 1
3 | 2
GROUP BY member_id는 member_id가 같은 행끼리 묶는다. 묶인 각 그룹에 COUNT(*)를 적용하면 그룹별 개수가 나온다.

여러 컬럼을 기준으로 묶을 수도 있다.
-- 회원별, 날짜별 주문 수
SELECT member_id, order_date, COUNT(*) AS 주문횟수
FROM orders
GROUP BY member_id, order_date;
GROUP BY 뒤에 컬럼을 콤마로 나열하면 그 조합이 같은 행끼리 묶인다.
GROUP BY로 그룹을 만든 뒤, 특정 조건을 만족하는 그룹만 남기고 싶을 때 HAVING을 쓴다.
-- 주문 횟수가 2번 이상인 회원만
SELECT member_id, COUNT(*) AS 주문횟수
FROM orders
GROUP BY member_id
HAVING COUNT(*) >= 2;
member_id | 주문횟수
----------+--------
1 | 3
3 | 2
처음엔 WHERE를 쓰면 되지 않나 싶다. 하지만 WHERE와 HAVING은 필터링하는 시점이 다르다.
WHERE — 그룹을 만들기 전에 행을 필터링한다HAVING — 그룹을 만든 후에 그룹을 필터링한다집계 함수 결과(COUNT(*), SUM() 등)를 조건으로 쓰려면 반드시 HAVING이어야 한다. WHERE 절에서는 집계 함수를 쓸 수 없다.
-- 오류: WHERE에서 집계 함수 사용 불가
SELECT member_id, COUNT(*)
FROM orders
WHERE COUNT(*) >= 2
GROUP BY member_id;
-- 올바른 방법
SELECT member_id, COUNT(*)
FROM orders
GROUP BY member_id
HAVING COUNT(*) >= 2;

둘을 같이 쓸 수도 있다. WHERE로 먼저 행을 걸러낸 뒤, GROUP BY로 묶고, HAVING으로 그룹을 다시 필터링한다.
-- 2026년 주문 중에서, 회원별 총 결제금액이 50000원 이상인 경우만
SELECT member_id, SUM(price) AS 총결제금액
FROM orders
WHERE YEAR(order_date) = 2026
GROUP BY member_id
HAVING SUM(price) >= 50000;
쿼리 실행 순서를 기억해두면 헷갈리지 않는다.
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
SELECT에서 정한 별칭을 HAVING에서 쓸 수 없는 이유도 여기에 있다. HAVING이 SELECT보다 먼저 실행되기 때문이다.
-- 오류: HAVING에서 별칭 사용 불가
SELECT member_id, SUM(price) AS 총결제금액
FROM orders
GROUP BY member_id
HAVING 총결제금액 >= 50000;
-- 올바른 방법
SELECT member_id, SUM(price) AS 총결제금액
FROM orders
GROUP BY member_id
HAVING SUM(price) >= 50000;
그룹 결과를 정렬할 때는 ORDER BY를 마지막에 붙인다.
-- 총 결제금액이 높은 순으로 정렬
SELECT member_id, SUM(price) AS 총결제금액
FROM orders
GROUP BY member_id
HAVING SUM(price) >= 10000
ORDER BY 총결제금액 DESC;
ORDER BY는 SELECT 이후에 실행되기 때문에 여기서는 별칭(총결제금액)을 써도 된다.
GROUP BY는 처음엔 단순히 "묶는 것"으로 보이는데, HAVING이 붙으면서 훨씬 다양한 분석이 가능해진다. 어떤 조건이 WHERE에 가야 하고 어떤 조건이 HAVING에 가야 하는지 — 그 기준은 "집계 전이냐, 집계 후냐"로 생각하면 된다.