안녕하세요, 20년 경력의 MySQL/MariaDB 개발자 ‘코딩하는곰’입니다. 데이터베이스를 다루다 보면 가장 빈번하게 마주하게 되는 작업이 바로 데이터의 통계를 내는 일입니다. “총 몇 건인지?”, “합계는 얼마인지?”, “평균은 어떻게 되지?”라는 질문에 답하기 위해 우리는 SQL의 핵심 집계 함수인 COUNT, SUM, AVG를 사용합니다. 이 함수들은 단순해 보이지만, 옵션과 함께 사용하는 방법, 주의사항, 성능까지 고려한다면 꽤 깊이 있는 이야기가 됩니다. 오늘은 이 세 가지 함수를 완벽하게 이해하고, 실무에서 바로 적용할 수 있는 다양한 예제와 팁을 자세히 소개해 드리겠습니다.
COUNT 함수는 말 그대로 행(Row)의 개수를 반환합니다. 가장 기본적이면서도 오용하기 쉬운 함수 중 하나입니다.
1. 기본 사용법: COUNT(*) vs COUNT(컬럼명)
COUNT(*): NULL 값을 포함한 모든 행의 수를 셉니다. 테이블의 전체 레코드 수를 알고 싶을 때 사용합니다.COUNT(컬럼명): 지정된 컬럼에서 NULL이 아닌 값의 개수만 셉니다. 특정 컬럼의 유효한 데이터 수를 확인할 때 유용합니다.-- 전체 직원 수 조회SELECT COUNT(*) AS total_employees FROM employees;-- 전화번호가 등록된 직원 수 조회 (phone_number 컬럼이 NULL이 아닌 경우만 카운트)SELECT COUNT(phone_number) AS employees_with_phone FROM employees;
2. COUNT(DISTINCT 컬럼명): 중복 제거 후 카운트
특정 컬럼의 고유한 값이 몇 개인지 알고 싶을 때 사용합니다. 예를 들어, 회사에 존재하는 모든 부서의 수나, 특정 기간 동안 주문을 한 고객의 수를 구할 때 필수적입니다.
-- 사내에 존재하는 고유 부서 번호의 개수SELECT COUNT(DISTINCT department_id) AS unique_departments FROM employees;-- 오늘 주문을 한 고유 고객 수SELECT COUNT(DISTINCT customer_id) AS unique_customers FROM orders WHERE order_date = CURDATE();
3. COUNT 함수와 GROUP BY의 조합
COUNT는 GROUP BY와 함께 사용될 때 그 진가를 발휘합니다. 각 그룹별로 데이터 개수를 집계할 수 있습니다.
-- 부서별 직원 수SELECT department_id, COUNT(*) AS num_employeesFROM employeesGROUP BY department_idORDER BY num_employees DESC;-- 카테고리별 상품 수SELECT category, COUNT(*) AS product_countFROM productsWHERE is_active = 1GROUP BY category;
성능 고려사항:
COUNT(*)는 일반적으로 COUNT(1)이나 COUNT(primary_key)와 성능 차이가 미미합니다. 최신 MySQL/MariaDB에서는 COUNT(*)를 최적화하여 처리하므로 가독성을 위해 COUNT(*)를 사용하는 것이 좋습니다.COUNT(DISTINCT column)은 큰 테이블에서 성능 저하를 일으킬 수 있습니다. 필요한 경우에만 사용하고, 인덱스가 있는 컬럼을 대상으로 하는 것이 좋습니다.
🚀 개발자 커리어를 준비하고 있다면, (Java 기초) 문자열 자르기(substring), 치환(replace), 검색(indexOf) 완벽 가이드를 참고해보세요.
SUM 함수는 지정된 숫자형 컬럼의 모든 값의 합계를 계산합니다. 매출 합계, 총 급여, 누적 방문자 수 등을 계산할 때 사용됩니다.
1. 기본 사용법
SUM 함수는 NULL 값을 자동으로 무시하고 계산합니다.
-- 모든 상품의 총 재고 수량SELECT SUM(stock_quantity) AS total_stock FROM products;-- 2023년도 총 매출액SELECT SUM(amount) AS total_sales FROM orders WHERE YEAR(order_date) = 2023;
2. 조건부 집계: SUM과 CASE WHEN, IF의 조합
SUM 함수 내부에 조건문을 사용하여 특정 조건을 만족하는 행만 합산할 수 있습니다. 이는 여러 개의 WHERE 조건을 가진 서브쿼리를 작성하는 것보다 효율적이고 가독성이 좋습니다.
-- 부서별 총 급여와, 그 중에서 보너스가 1000 이상인 직원들의 급여 합계를 동시에 조회SELECTdepartment_id,SUM(salary) AS total_salary,SUM(CASE WHEN bonus >= 1000 THEN salary ELSE 0 END) AS high_bonus_salaryFROM employeesGROUP BY department_id;-- IF문을 사용한 동일한 예제 (MariaDB/MySQL 스타일)SELECTdepartment_id,SUM(salary) AS total_salary,SUM(IF(bonus >= 1000, salary, 0)) AS high_bonus_salaryFROM employeesGROUP BY department_id;
3. SUM과 JOIN의 활용 여러 테이블을 조인한 후 관련 데이터의 총합을 구하는 것은 실무에서 매우 흔한 패턴입니다.
-- 각 고객별 총 주문 금액 조회 (고객명 포함)SELECTc.customer_id,c.customer_name,SUM(o.amount) AS total_order_amountFROM customers cINNER JOIN orders o ON c.customer_id = o.customer_idGROUP BY c.customer_id, c.customer_nameORDER BY total_order_amount DESC;
주의사항:
SUM 함수는 정수형(INT) 컬럼에 적용하면 결과도 정수형이지만, 합계가 범위를 초과할 경우 오버플로우가 발생할 수 있습니다. BIGINT나 DECIMAL 타입을 사용하는 것이 안전합니다.SUM은 숫자형 데이터에만 사용 가능합니다. 문자열이나 날짜형에 사용하면 에러가 발생합니다.
웹사이트에 접속하면 서버에 남는 정보 중 하나가 바로 IP입니다. 궁금하다면 내 IP와 위치 확인하기를 통해 지금 바로 확인해보세요.
AVG 함수는 숫자형 컬럼 값의 평균을 계산합니다. SUM(컬럼) / COUNT(컬럼)과 동일한 연산을 수행하며, NULL 값은 계산에서 제외됩니다.
1. 기본 사용법
-- 전체 직원의 평균 급여SELECT AVG(salary) AS average_salary FROM employees;-- 각 제품 카테고리별 평균 가격SELECT category, AVG(price) AS avg_priceFROM productsGROUP BY category;
2. NULL 값 처리의 중요성
AVG 함수는 분자(SUM)와 분모(COUNT) 모두에서 NULL 값을 제외합니다. 이는 때로는 우리가 원하는 논리와 다를 수 있습니다. 예를 들어, 성적 테이블에서 시험을 보지 않아 NULL인 학생을 0점 처리하여 평균에 포함시키고 싶을 수 있습니다.
-- NULL을 0으로 간주한 평균 점수 계산 (IFNULL 또는 COALESCE 사용)SELECTAVG(IFNULL(score, 0)) AS avg_score_with_null_as_zero,AVG(score) AS avg_score_ignore_null -- NULL 무시FROM student_grades;
3. 정밀도 문제와 DECIMAL 타입
AVG 함수의 결과는 입력 값의 데이터 타입에 영향을 받습니다. 정수형(INT) 컬럼의 평균을 구하면 소수점 이하가 잘릴 수 있습니다. 정확한 소수점 계산이 필요하다면, CAST 함수를 사용하여 DECIMAL 타입으로 변환 후 계산하거나, 컬럼 자체를 DECIMAL로 정의하는 것이 좋습니다.
-- 정수형 컬럼의 평균 (소수점 손실 가능성)SELECT AVG(int_column) FROM my_table;-- DECIMAL로 변환하여 정확한 평균 계산SELECT AVG(CAST(int_column AS DECIMAL(10,2))) FROM my_table;
4. 고급 활용: 가중 평균 계산 단순 평균이 아닌, 가중치를 적용한 평균을 계산해야 할 때가 있습니다. 예를 들어, 각 항목의 중요도(가중치)에 따라 평균을 내는 경우입니다.
-- 각 평가 항목별 점수와 가중치를 이용한 최종 평균 점수 계산SELECTstudent_id,SUM(score * weight) / SUM(weight) AS weighted_average_scoreFROM evaluationsGROUP BY student_id;
통계 함수 종합 예제:
하나의 쿼리에서 COUNT, SUM, AVG를 모두 사용하여 데이터에 대한 종합적인 리포트를 생성해 보겠습니다.
-- 2023년 분기별 매출 리포트SELECTQUARTER(order_date) AS quarter,COUNT(*) AS order_count, -- 주문 건수SUM(amount) AS total_sales, -- 총 매출AVG(amount) AS average_order_value -- 평균 주문 금액FROM ordersWHERE YEAR(order_date) = 2023GROUP BY QUARTER(order_date)ORDER BY quarter;
로또 번호 선택이 어려울 때는, AI가 분석한 번호 추천과 통계 정보를 제공하는 지니로또AI를 활용해보세요.
지금까지 MySQL과 MariaDB에서 데이터 통계의 기초를 이루는 세 가지 함수, COUNT, SUM, AVG에 대해 자세히 알아보았습니다. 이 함수들은 단독으로도 유용하지만, GROUP BY, CASE WHEN, JOIN 등 다른 SQL 절과 조합될 때 무궁무진한 가능성을 발휘합니다. 실무에서는 이 함수들을 얼마나 잘 활용하느냐가 데이터 분석의 효율성을 결정짓는 경우가 많습니다. 특히 NULL 값 처리와 데이터 타입에 따른 정밀도 문제는 미리 인지하고 있어야 하는 함정입니다. ‘코딩하는곰’의 블로그가 여러분의 데이터베이스 여정에 작은 도움이 되었기를 바랍니다. 다음 시간에는 더 심화된 집계 함수나 윈도우 함수에 대해 다루어 보겠습니다. 궁금한 점이 있다면 언제든지 댓글로 남겨주세요!
📌 영양제 선택이 어려울 때 참고하면 좋은, 메가 루테인를 참고해보세요.
