SQLSQL 기초 · 4입문

집계 함수와 GROUP BY — 통계 계산하기

SQLGROUP BYCOUNTSUMAVGHAVING

집계 함수

-- 전체 행 수
SELECT COUNT(*) FROM employees;                -- 6

-- 특정 열 값이 있는 행 수 (NULL 제외)
SELECT COUNT(department) FROM employees;

-- 합계
SELECT SUM(salary) FROM employees;             -- 30200000

-- 평균
SELECT AVG(salary) FROM employees;             -- 5033333.33

-- 최대/최소
SELECT MAX(salary), MIN(salary) FROM employees;

-- 한 번에 여러 집계
SELECT
    COUNT(*) AS 직원수,
    SUM(salary) AS 급여총액,
    ROUND(AVG(salary), 0) AS 평균급여,
    MAX(salary) AS 최고급여,
    MIN(salary) AS 최저급여
FROM employees;

GROUP BY: 그룹별 집계

-- 부서별 인원 수
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department;

-- 결과
-- department | headcount
-- -----------|----------
-- 개발팀      | 3
-- 마케팅팀    | 2
-- 디자인팀    | 1

-- 부서별 평균 급여
SELECT
    department,
    COUNT(*) AS headcount,
    ROUND(AVG(salary), 0) AS avg_salary,
    SUM(salary) AS total_salary
FROM employees
GROUP BY department
ORDER BY avg_salary DESC;

HAVING: 그룹 조건 필터링

WHERE는 행을 필터링, HAVING은 그룹을 필터링합니다.

-- 인원 2명 이상인 부서만
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2;

-- 평균 급여 500만 이상 부서
SELECT department, ROUND(AVG(salary), 0) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) >= 5000000;

WHERE vs HAVING

-- WHERE: GROUP BY 전에 적용 (원본 행 필터)
-- HAVING: GROUP BY 후에 적용 (그룹 필터)

-- 활성 직원만 대상으로 → 부서별 집계 → 인원 2명 이상 필터
SELECT department, COUNT(*) AS headcount
FROM employees
WHERE is_active = TRUE          -- 행 필터 (GROUP BY 전)
GROUP BY department
HAVING COUNT(*) >= 2;           -- 그룹 필터 (GROUP BY 후)

SELECT 실행 순서

flowchart TB
    F["FROM 테이블 선택"]
    W["WHERE 행 필터"]
    G["GROUP BY 그룹화"]
    H["HAVING 그룹 필터"]
    S["SELECT 열 선택"]
    O["ORDER BY 정렬"]
    L["LIMIT 개수 제한"]

    F --> W --> G --> H --> S --> O --> L

집계 + JOIN 조합

-- 고객별 주문 총액 (상위 5명)
SELECT
    c.name,
    COUNT(o.id) AS order_count,
    SUM(o.amount) AS total_spent
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name
ORDER BY total_spent DESC NULLS LAST
LIMIT 5;

ROLLUP: 소계 포함

-- 부서별 소계 + 전체 합계
SELECT
    COALESCE(department, '전체') AS department,
    SUM(salary) AS total_salary
FROM employees
GROUP BY ROLLUP(department);

-- 결과
-- department | total_salary
-- -----------|-------------
-- 개발팀      | 17300000
-- 디자인팀    | 4800000
-- 마케팅팀    | 8100000
-- 전체        | 30200000   ← ROLLUP이 추가한 전체 합계

정리

함수/절역할
COUNT(*)행 수
SUM(col)합계
AVG(col)평균
MAX/MIN(col)최대/최소
GROUP BY col그룹화
HAVING 조건그룹 조건 필터
ROUND(n, d)소수점 반올림

다음 편에서는 서브쿼리 — 쿼리 안에 쿼리를 넣어 복잡한 조건을 처리하는 방법을 배웁니다.

궁금한 점이 있으신가요?

협업·의뢰는 아래로, 가벼운 소통은 인스타그램 @bluefox._.hi도 환영이에요.