모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.

9강 / 전체 24강

집계 함수

10분 읽기 조회 0

COUNT·SUM·AVG·MAX·MIN으로 여러 행을 단 하나의 요약 값으로 집계하는 집계 함수의 원리와 활용법을 익힙니다.

🎯 학습 목표

이 강을 마치면 여러 행에 걸친 데이터를 하나의 요약 값으로 집계하는 집계 함수 다섯 가지(COUNT, SUM, AVG, MAX, MIN)를 자유롭게 사용할 수 있습니다. "회원이 총 몇 명인지", "전체 주문 금액 합계는 얼마인지", "도서 평균 가격은 얼마인지"처럼 실무에서 가장 자주 필요한 통계 쿼리를 작성할 수 있게 됩니다. 또한 NULL이 집계 함수에 미치는 영향을 이해해 정확한 결과를 얻을 수 있습니다.

💡 집계 함수란 무엇인가

이 섹션에서는 집계 함수의 개념과 단일 행 함수(8강)와의 차이를 살펴보겠습니다.

8강에서 배운 ROUND(), ABS()는 단일 행 함수(Scalar Function)입니다. 각 행에 독립적으로 적용되어 행마다 하나의 결과를 반환합니다. 예를 들어 books 테이블에 7개 행이 있으면, ROUND(price, 0)도 7개의 결과를 반환합니다.

반면 집계 함수(Aggregate Function)는 여러 행을 받아 하나의 요약 값을 반환합니다. COUNT(*)는 7개 행을 받아 7이라는 단 하나의 숫자를 반환합니다. 이것이 집계 함수의 핵심 특성입니다. 단일 행 함수는 행의 수를 줄이지 않고, 집계 함수는 여러 행을 하나로 압축합니다.

SQL의 집계 함수 다섯 가지를 정리하면 다음과 같습니다.

함수역할NULL 처리
COUNT(*)전체 행 수 (NULL 포함)NULL 포함
COUNT(열)특정 열이 NULL이 아닌 행 수NULL 제외
SUM(열)열 값의 합계NULL 제외
AVG(열)열 값의 평균NULL 제외 (개수도 줄어듦)
MAX(열)열 값 중 최댓값NULL 제외
MIN(열)열 값 중 최솟값NULL 제외

NULL 처리 방식이 중요합니다. COUNT(*)를 제외한 모든 집계 함수는 NULL 값을 무시하고 계산합니다. 이 때문에 COUNT(*)와 COUNT(열)의 결과가 달라질 수 있습니다.

🔢 COUNT — 행 수 세기

이 섹션에서는 가장 자주 사용하는 집계 함수 COUNT를 자세히 살펴보겠습니다.

COUNT(*)는 WHERE 조건을 통과한 모든 행의 수를 셉니다. NULL 포함입니다.

-- 전체 회원 수
SELECT COUNT(*) AS 전체회원수
FROM members;

-- 전체 도서 수
SELECT COUNT(*) AS 전체도서수
FROM books;

-- VIP 회원 수
SELECT COUNT(*) AS VIP회원수
FROM members
WHERE grade = 'VIP';

첫 번째는 6(홍길동 추가분 포함), 두 번째는 7, 세 번째는 2가 반환됩니다. WHERE를 사용하면 조건을 만족하는 행만 COUNT합니다.

COUNT(열)는 해당 열의 값이 NULL이 아닌 행 수만 셉니다.

-- grade가 설정된 회원 수 (NULL 제외)
SELECT
  COUNT(*) AS 전체회원수,
  COUNT(grade) AS 등급설정회원수
FROM members;

COUNT(*)는 6, COUNT(grade)는 5가 나타납니다. 6강에서 추가한 홍길동(grade = NULL)이 COUNT(grade)에서 제외되기 때문입니다. 이 차이를 이해하면 NULL이 있는 열의 집계를 정확하게 처리할 수 있습니다.

DISTINCT와 결합하면 유니크한 값의 수를 셀 수 있습니다.

-- 몇 가지 카테고리가 있는지
SELECT COUNT(DISTINCT category) AS 카테고리수
FROM books;

-- 주문한 회원이 총 몇 명인지 (중복 제거)
SELECT COUNT(DISTINCT member_id) AS 주문회원수
FROM orders;

첫 번째는 3(IT, 경제, 소설), 두 번째는 주문 테이블에서 중복 없는 회원 수가 반환됩니다.

➕ SUM과 AVG — 합계와 평균

이 섹션에서는 수치 열의 합계와 평균을 구하는 SUM과 AVG를 살펴보겠습니다.

SUM(열)은 수치 열의 모든 값을 더합니다. NULL은 0처럼 취급하는 게 아니라 완전히 무시합니다.

-- 도서 전체 재고 합계
SELECT SUM(stock) AS 총재고수량
FROM books;

-- IT 카테고리 도서 가격 합계
SELECT SUM(price) AS IT도서가격합계
FROM books
WHERE category = 'IT';

첫 번째는 books 테이블의 모든 재고(stock)를 더한 값, 두 번째는 IT 카테고리 3권(22000 + 28000 + 33000 = 83000)이 반환됩니다.

AVG(열)는 수치 열의 평균값을 계산합니다. NULL 행을 제외한 합계 ÷ NULL 제외 행 수입니다.

-- 도서 평균 가격
SELECT
  AVG(price) AS 평균가격,
  ROUND(AVG(price), 0) AS 평균가격_정수
FROM books;

-- 카테고리별 평균 가격 (10강 GROUP BY로 더 정확히 가능)
SELECT AVG(price) AS IT평균가격
FROM books
WHERE category = 'IT';

전체 평균은 7개 도서 가격의 합 ÷ 7입니다. ROUND를 결합해 소수점을 없앨 수 있습니다.

NULL이 AVG에 미치는 영향을 이해하는 것이 중요합니다. 만약 stock이 NULL인 행이 있다면 AVG(stock)는 NULL을 제외한 나머지 행으로만 평균을 냅니다. 이는 "NULL = 0으로 취급"과 전혀 다른 결과입니다. 재고가 없어서 NULL인지, 아직 파악 안 되어 NULL인지에 따라 AVG(stock)와 AVG(COALESCE(stock, 0))는 다른 의미를 가집니다.

🏆 MAX와 MIN — 최댓값과 최솟값

이 섹션에서는 열에서 가장 크거나 작은 값을 찾는 MAX와 MIN을 살펴보겠습니다.

MAX(열)과 MIN(열)은 수치뿐 아니라 문자열·날짜에도 사용 가능합니다. 문자열은 사전 순서(유니코드) 기준으로 가장 나중(MAX)·가장 앞(MIN) 값을 반환합니다.

-- 가장 비싼/저렴한 도서 가격
SELECT
  MAX(price) AS 최고가,
  MIN(price) AS 최저가,
  MAX(price) - MIN(price) AS 가격범위
FROM books;

최고가 33,000, 최저가 13,000, 가격 범위 20,000이 반환됩니다.

-- 가장 최근/오래된 주문 날짜
SELECT
  MAX(order_date) AS 최신주문일,
  MIN(order_date) AS 최초주문일
FROM orders;

-- 가나다 순서 첫 번째/마지막 회원 이름
SELECT
  MIN(name) AS 가나다첫번째,
  MAX(name) AS 가나다마지막
FROM members;

날짜 문자열('YYYY-MM-DD')은 사전 순서가 날짜 순서와 일치하므로 MAX/MIN이 올바른 최신·최고일을 반환합니다.

7강에서 ORDER BY + LIMIT 1로 최댓값 행 전체를 가져올 수 있었습니다. MAX/MIN은 값 하나만 반환하지만, 값 외에 다른 열 정보도 함께 보고 싶다면 16강(서브쿼리)에서 배울 패턴이 필요합니다. 지금은 집계 값 자체를 구하는 데 집중합니다.

🔗 여러 집계 함수 조합

이 섹션에서는 하나의 SELECT에서 여러 집계 함수를 동시에 사용하는 방법을 살펴보겠습니다.

하나의 SELECT에서 여러 집계 함수를 나열하면 한 번의 쿼리로 여러 통계를 얻을 수 있습니다.

-- 도서 관련 주요 통계 한 번에 조회
SELECT
  COUNT(*)              AS 총도서수,
  SUM(price)            AS 가격합계,
  ROUND(AVG(price), 0)  AS 평균가격,
  MAX(price)            AS 최고가,
  MIN(price)            AS 최저가,
  SUM(stock)            AS 총재고
FROM books;

결과는 단 한 행으로, 도서 현황을 한눈에 파악할 수 있는 대시보드 쿼리가 됩니다.

WHERE를 결합하면 특정 조건에서의 통계를 구할 수 있습니다.

-- 완료된 주문의 통계
SELECT
  COUNT(*)         AS 완료주문수,
  SUM(quantity)    AS 총주문수량,
  AVG(quantity)    AS 평균주문수량
FROM orders
WHERE status = 'DONE';

-- PENDING 또는 CANCEL 상태 주문 수 비교
SELECT
  COUNT(CASE WHEN status = 'PENDING' THEN 1 END) AS 대기중,
  COUNT(CASE WHEN status = 'CANCEL'  THEN 1 END) AS 취소됨,
  COUNT(CASE WHEN status = 'DONE'    THEN 1 END) AS 완료됨
FROM orders;

두 번째 쿼리에서 CASE WHEN은 18강에서 자세히 배웁니다. 여기서는 "조건부 COUNT"가 가능하다는 것만 알아두세요. 이 패턴은 피벗 집계(Pivot Aggregation)라고 불리며 보고서 쿼리에서 매우 자주 씁니다.

⚠️ 집계 함수의 주의사항

이 섹션에서는 집계 함수 사용 시 자주 마주치는 오류와 함정을 살펴보겠습니다.

첫 번째 주의사항은 집계 함수와 일반 열을 SELECT에서 함께 쓸 수 없다는 것입니다.

-- 오류! title은 일반 열, COUNT(*)는 집계 함수
SELECT title, COUNT(*)
FROM books;

-- 올바른 방법 1: 집계 함수만 사용
SELECT COUNT(*) FROM books;

-- 올바른 방법 2: GROUP BY로 그룹화 (10강)
SELECT category, COUNT(*) FROM books GROUP BY category;

title은 각 행마다 다른 값을 가지지만 COUNT(*)는 하나의 값을 반환합니다. 이 두 가지를 어떻게 표시해야 할지 데이터베이스가 알 수 없어 오류가 발생합니다. 일반 열과 함께 집계 함수를 쓰려면 반드시 GROUP BY가 필요하며, 이는 10강에서 배웁니다.

두 번째는 AVG의 NULL 처리입니다. 예를 들어 10명 중 3명의 성적이 NULL(미응시)이라면 AVG(score)는 7명의 합 ÷ 7입니다. "전체 10명의 평균"을 구하고 싶다면 AVG(COALESCE(score, 0))처럼 NULL을 0으로 치환해야 합니다.

-- NULL을 0으로 대체한 평균 (NULL = 0점으로 취급)
SELECT AVG(COALESCE(quantity, 0)) AS 실제평균
FROM orders;

세 번째는 집계 결과에 ORDER BY 적용 가능하다는 점입니다. 실행 순서는 FROM → WHERE → 집계 → ORDER BY이므로, ORDER BY에서는 집계 함수 별칭이나 식을 사용할 수 있습니다. 10강의 GROUP BY와 결합하면 "카테고리별 평균 가격 내림차순 정렬" 같은 쿼리를 작성할 수 있게 됩니다.

📝 핵심 요약

이번 강에서 배운 내용을 정리하겠습니다.

함수역할NULL 처리예시
COUNT(*)전체 행 수포함COUNT(*) AS 총회원수
COUNT(열)NULL 아닌 행 수제외COUNT(grade)
COUNT(DISTINCT 열)유니크한 값의 수제외COUNT(DISTINCT category)
SUM(열)합계제외SUM(price)
AVG(열)평균 (NULL 행 분모에서 제외)제외AVG(price)
MAX(열)최댓값제외MAX(order_date)
MIN(열)최솟값제외MIN(price)

집계 함수는 SQL로 할 수 있는 가장 강력한 작업 중 하나입니다. 하지만 지금까지는 테이블 전체 또는 WHERE로 필터된 전체 행에 대해 집계를 구했습니다. 다음 10강에서는 GROUP BY를 배웁니다. "카테고리별 도서 수", "등급별 회원 수", "월별 주문 건수"처럼 그룹을 나누어 각 그룹마다 집계하는 강력한 기능을 익히게 됩니다. GROUP BY와 집계 함수의 조합은 실무 SQL의 핵심입니다.

관련 주제

  • COUNT SUM AVG
  • MAX MIN
  • 집계 함수
  • NULL 처리
  • 통계 쿼리
  • 개발·프로그래밍
  • 개발·프로그래밍 강의
  • SQL·데이터베이스 입문 24강
  • 무료강의
  • 무료 온라인 강의
  • NUGUNA
  • 누구나

📚 시리즈 전체 공유

SQL·데이터베이스 입문 24강

이 강의가 속한 시리즈는 총 24강, 모두 무료입니다. 처음부터 배우려는 동료에게 시리즈 전체를 알려 주세요.

댓글

0/1000

불러오는 중...