풀스택 백엔드 2026.06.30

syyu21b·2026년 6월 30일

풀스택 - 백엔드

목록 보기
39/49
post-thumbnail

[SECTION09. 집계함수와 GROUP BY / HAVING]

  • 집계함수 = 여러 행의 값을 하나로 합쳐서 계산하는 함수로, “전체 게시글 수”, “평균 조회수”처럼 통계성 정보를 뽑을 때 사용
함수의미
COUNT(컬럼 또는 *)행의 개수
SUM(컬럼)합계
AVG(컬럼)평균
MAX(컬럼)최댓값
MIN(컬럼)최솟값

1-1. COUNT

-- 전체 게시글 수
SELECT COUNT(*) FROM board;

-- content가 NULL이 아닌 게시글 수 (컬럼명을 넣으면 NULL은 제외하고 셈)
SELECT COUNT(content) FROM board;

1-2. SUM, AVG

-- 전체 게시글의 조회수 합계
SELECT SUM(view_count) FROM board;

-- 전체 게시글의 평균 조회수
SELECT AVG(view_count) FROM board;

1-3. MAX, MIN

-- 조회수가 가장 높은 값
SELECT MAX(view_count) FROM board;

-- 조회수가 가장 낮은 값
SELECT MIN(view_count) FROM board;

1-4. 여러 집계함수 동시에 사용

select 
	count(*) as 전체게시글수,
	max(view_count) as 조회수최댓값, 
	min(view_count) as 조회수최솟값, 
	avg(view_count) as 조회수평균, 
	sum(view_count) as 조회수총합
from board

AS로 결과 컬럼에 별명(alias)을 붙이면 결과를 읽기 쉬워집니다.


2. GROUP BY — 그룹별로 묶기

집계함수를 전체 테이블이 아니라 그룹별로 적용하고 싶을 때 사용합니다.

-- 카테고리별 게시글 수
SELECT category_id, COUNT(*) AS board_count
FROM board
GROUP BY category_id;

결과 예시:

category_idboard_count
16
23
34
47

category_id가 같은 행끼리 묶어서, 그 안에서 COUNT를 계산합니다.

-- 회원별 작성한 게시글 수
SELECT member_id, COUNT(*) AS board_count
FROM board
GROUP BY member_id;
-- 카테고리별 평균 조회수
SELECT category_id, AVG(view_count) AS avg_view
FROM board
GROUP BY category_id;

2-1. GROUP BY를 쓸 때 주의할 점

SELECT에 나열하는 컬럼은 GROUP BY에 포함된 컬럼 또는 집계함수로 감싼 컬럼이어야 합니다.

-- ❌ 잘못된 예: title은 그룹화 기준도 아니고 집계함수도 아님
SELECT category_id, title, COUNT(*) FROM board GROUP BY category_id;

-- ✅ 올바른 예
SELECT category_id, COUNT(*) FROM board GROUP BY category_id;

3. HAVING — 그룹화된 결과에 조건 걸기

WHERE는 그룹화하기 행 단위로 조건을 거는 것이고, HAVING은 그룹화한 이후 그룹 단위로 조건을 거는 것입니다.

-- 게시글이 5개 이상인 카테고리만 조회
SELECT category_id, COUNT(*) AS board_count
FROM board
GROUP BY category_id
HAVING COUNT(*) >= 5;

select category_id, count(*) as board_count
from board
group by category_id
having board_count >= 5
-- 평균 조회수가 0보다 큰 카테고리만 조회
SELECT category_id, AVG(view_count) AS avg_view
FROM board
GROUP BY category_id
HAVING AVG(view_count) > 0;

3-1. WHERE와 HAVING을 함께 사용

-- member_id가 1~5인 게시글만 대상으로, 카테고리별 게시글 수를 구하고,
-- 그중 게시글 수가 2개 이상인 카테고리만 조회
SELECT category_id, COUNT(*) AS board_count
FROM board
WHERE member_id BETWEEN 1 AND 5
GROUP BY category_id
HAVING COUNT(*) >= 2;

실행 순서: WHERE(행 필터링) → GROUP BY(그룹화) → HAVING(그룹 필터링) → ORDER BY(정렬)

WHERE는 집계함수를 사용할 수 없습니다 (WHERE COUNT(*) >= 2는 에러). 집계 결과에 조건을 걸려면 반드시 HAVING을 사용해야 합니다.


4. 실전 활용 예시

4-1. 게시글을 가장 많이 쓴 회원 TOP 3

SELECT member_id, COUNT(*) AS board_count
FROM board
GROUP BY member_id
ORDER BY board_count DESC
LIMIT 3;

4-2. 댓글이 가장 많이 달린 게시글

SELECT board_id, COUNT(*) AS comment_count
FROM comment
GROUP BY board_id
ORDER BY comment_count DESC
LIMIT 1;

4-3. 좋아요를 한 번도 못 받은 게시글이 아닌, 좋아요 분포 보기

SELECT board_id, COUNT(*) AS like_count
FROM board_like
GROUP BY board_id
ORDER BY like_count DESC;

정리

  • COUNT, SUM, AVG, MAX, MIN으로 여러 행의 값을 하나로 집계할 수 있다.
  • GROUP BY는 특정 컬럼을 기준으로 데이터를 그룹화하며, SELECT에는 그룹화 기준 컬럼 또는 집계함수만 올 수 있다.
  • HAVING은 그룹화된 결과에 조건을 걸 때 사용하며, WHERE는 집계함수를 조건으로 쓸 수 없다.
  • 쿼리 실행 순서는 WHERE → GROUP BY → HAVING → ORDER BY이다.

SQL 연습 문제

1. board 테이블에서 전체 게시글 수와 평균 조회수를 함께 조회하는 SQL을 작성하시오.

select 
	count(*) as 전체게시글수,
	avg(view_count) as 평균조회수
from  board

2. comment 테이블에서 게시글(board_id)별 댓글 수를 조회하는 SQL을 작성하시오.

select 
	board_id,
	count(*) as 댓글수
from comments
group by board_id

3. board 테이블에서 회원(member_id)별 게시글 수가 많은 순으로 정렬해서 조회하는 SQL을 작성하시오.

select 
	member_id,
	count(*) as 작성게시글수
from board
group by board_id
order by 작성게시글수 desc

4. board 테이블에서 카테고리(category_id)별 게시글 수를 구하고, 그중 게시글 수가 3개 이상인 카테고리만 조회하는 SQL을 작성하시오.

select category_id, count(*) as 게시글수
from  board
group by category_id
having 게시글수 >= 3;

5. board_like 테이블에서 게시글별 좋아요 수를 구하고, 좋아요 수가 가장 많은 게시글 1개만 조회하는 SQL을 작성하시오.

select board_id, count(*) as 좋아요수
from  
board_like
group by  board_id
order by 좋아요수 desc
limit 1

6. board 테이블에서 category_id가 1 또는 4인 게시글만 대상으로, 회원별 게시글 수를 구하고, 그중 2개 이상 쓴 회원만 조회하는 SQL을 작성하시오. (WHERE와 HAVING을 모두 사용)

select member_id, count(*) as 회원별게시글수
from board
where category_id in (1, 4)
group by member_id
having 회원별게시글수 >= 2

7. comment 테이블에서 회원(member_id)별로 작성한 댓글 수를 구하고, 댓글을 2개 이상 작성한 회원을 구하시오.

select member_id, count(*) 댓글수
from 
comments
group by member_id
having 댓글수 >= 2

0개의 댓글