AD JB Toolbox 01

MariaDB 강좌 / COUNT·SUM·AVG·MIN·MAX로 집계하기

COUNT·SUM·AVG·MIN·MAX는 여러 행을 개수·합계·평균·최솟값·최댓값으로 요약합니다. COUNT(*)는 행을 세고 COUNT(열)은 NULL이 아닌 값을 세며, 다른 집계도 NULL과 빈 결과를 특별하게 처리하므로 분모와 미입력의 의미를 먼저 정해야 합니다.

집계할 대상과 측정 단위부터 정하기

상품 종류 수와 총 재고 수량, 평균 단가와 재고 금액 합계는 서로 다릅니다. 상품 한 행이 무엇을 나타내는지, 숫자의 단위가 원인지 개인지, 같은 상품이 여러 행에 반복되는지 먼저 확인합니다. 숫자를 더하는 문법만 맞아도 업무상 합계가 틀릴 수 있습니다. 그룹마다 별도 합계가 필요하면 GROUP BY·HAVING으로 묶고 집계 결과 걸러내기로 확장합니다. 테이블을 연결한 뒤에는 여러 테이블 JOIN하기: 중복 행과 집계 오류 확인처럼 행 증가로 합계가 중복되는지도 확인해야 합니다.

요구 사항 표현 단위
상품 행 수 COUNT(*) 행
알려진 메모 수 COUNT(note) NULL이 아닌 값
재고 총수량 SUM(stock) 개
평균 재고 AVG(stock) 상품당 개
재고 금액 SUM(price*stock) 원

메모 상태와 재고가 섞인 상품 데이터 준비하기

학습용 MariaDB 서버의 shopcourse에 course_user로 접속합니다. 명령줄 클라이언트와 UTF-8 SQL 파일 실행 방법대로 코드를 UTF-8 파일에 저장하고 SOURCE C:/mariadb-lab/lesson.sql;처럼 실제 파일 경로로 실행할 수 있습니다. SQL 문은 운영체제 터미널이 아닌 MariaDB 연결 안에서 실행합니다.

먼저 SELECT VERSION(), DATABASE();와 SHOW TABLES;로 대상 서버·DB·이름 중복을 확인합니다. 아래 products_22_lab는 이 글의 독립된 연습용 이름입니다. 이미 존재하면 정의와 행을 확인하고, 보관할 자료가 없는 이 글의 실습 테이블임이 확실할 때만 마지막 절의 정리 순서로 지운 뒤 다시 만듭니다. 기존 강좌의 동명 없는 테이블이나 운영 데이터는 삭제하지 않습니다.

USE shopcourse;
CREATE TABLE products_22_lab (
  product_id INT NOT NULL AUTO_INCREMENT,
  product_name VARCHAR(100) NOT NULL,
  category VARCHAR(30) NOT NULL,
  price DECIMAL(10,2) NOT NULL,
  stock INT NOT NULL DEFAULT 0,
  note VARCHAR(100) NULL DEFAULT NULL,
  PRIMARY KEY (product_id),
  CONSTRAINT ck_p22_price CHECK (price >= 0),
  CONSTRAINT ck_p22_stock CHECK (stock >= 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO products_22_lab (product_id,product_name,category,price,stock,note) VALUES (1, '노트', '문구', 3500.00, 20, NULL),
  (2, '볼펜', '문구', 1500.00, 0, ''),
  (3, '머그컵', '생활', 8000.00, 12, '선물 포장'),
  (4, '스탠드', '생활', 25000.00, 5, NULL),
  (5, '파일', '문구', 1500.00, 50, ''),
  (6, '케이블', '전자', 8000.00, 0, '호환 확인');

여섯 행 중 메모가 NULL인 행은 두 개, 빈 문자열인 행은 두 개입니다. 재고가 0인 상품도 실제로 존재하는 상품이므로 행 개수에 포함합니다. NULL 처리의 의미를 함께 확인하면 집계에서 값이 빠지는 이유를 이해하기 쉽습니다.

한 번의 조회에서 서로 다른 집계를 비교하기

SELECT COUNT(*) AS all_rows,COUNT(note) AS known_notes,
 SUM(stock) AS stock_total,AVG(stock) AS stock_average,
 MIN(price) AS lowest_price,MAX(price) AS highest_price,
 SUM(price*stock) AS inventory_total
FROM products_22_lab;
결과 열 예상 값 해석
all_rows 6 모든 상품 행
known_notes 4 빈 문자열은 값이므로 포함
stock_total 87 20+0+12+5+50+0
stock_average 14.5와 같은 값 표시 소수 자릿수는 타입에 따라 다름
lowest_price / highest_price 1500.00 / 25000.00 가격의 경계
inventory_total 366000.00 행별 가격×재고를 합산

AVG(stock)는 행마다 stock을 읽고 NULL이 아닌 값의 합을 해당 값 수로 나눕니다. 0은 평균의 분모와 분자에 포함됩니다. NULL은 미확인 값이고 0은 확인된 수량이 0이라는 차이를 유지하세요. COUNT의 별표·열 기준와 AVG의 NULL 처리를 참고할 수 있습니다.

조건에 맞는 행이 없을 때 확인하기

SELECT COUNT(*),SUM(stock),AVG(stock),COALESCE(SUM(stock),0)
FROM products_22_lab WHERE price < 0;

결과는 0, NULL, NULL, 0입니다. COUNT는 행이 없으면 0이지만 합계와 평균은 NULL이므로 화면 표시와 실제 계산의 의미를 분리합니다. 재고 금액이 없다는 의미로 합계를 0으로 표시할 수 있어도, 표본이 전혀 없는 평균을 실제 평균 0으로 기록하는 것은 다른 판단입니다. SUM의 빈 결과 처리를 확인하세요.

행별 계산과 집계 순서를 구분하기

SUM(price*stock)는 각 행의 재고 금액을 먼저 구해 더합니다. SUM(price)*SUM(stock)는 전체 가격 합과 전체 재고 합을 곱하므로 전혀 다른 값입니다. 결과가 커 보인다는 이유로 무조건 소수점 문제라고 판단하지 말고 계산의 대상과 순서를 먼저 확인합니다.

SELECT product_id,price,stock,price*stock AS row_value
FROM products_22_lab ORDER BY product_id;

MIN(price)와 MAX(price)는 가격 값만 반환하며 그 가격의 상품명까지 자동으로 골라 주지는 않습니다. 같은 최저가 상품이 여러 개일 수 있으므로 실제 상품 목록이 필요하면 가격 조건이나 정렬 기준을 별도로 정합니다. 집계 옆에 임의의 비집계 열을 붙여 대표 상품이라고 해석하지 않습니다.

중복·누락을 확인하고 연습 데이터 정리하기

처음에는 기본키를 포함한 전체 행을 조회하고 수기로 작은 합계를 대조합니다. 원래 여섯 상품이 맞는지, NULL이 0으로 임의 치환되지 않았는지, JOIN으로 행이 늘어난 결과에 바로 합산하지 않았는지를 확인합니다. 큰 값의 합계는 결과 타입과 애플리케이션의 숫자 처리 범위도 함께 검토해야 합니다.

반복하기 전 현재 DB와 실제 정의·행을 확인하고 필요한 자료를 백업합니다. 보관할 데이터가 없는 이 글의 전용 실습 객체만 아래 순서로 정리합니다. 외래키가 있으면 자식부터 지웁니다. DROP TABLE은 구조와 데이터를 모두 없애며 일반적인 ROLLBACK으로 복원되지 않으므로 취소 가능한 DML 실습과 분리합니다.

DROP TABLE shopcourse.products_22_lab;
같은 카테고리의 다른 글
MariaDB 강좌 / UPDATE·DELETE를 실행하기 전 대상 행 확인하기

MariaDB 강좌 / UPDATE·DELETE를 실행하기 전 대상 행 확인하기

UPDATE·DELETE 전에 기본키와 현재값으로 대상 행을 확인하고, InnoDB 트랜잭션에서 수정·삭제 결과를 검증한 뒤 취소합니다. 영향받은 행 수와 ROLLBACK의 적용 한계도 설명합니다.

MariaDB 강좌 / 로컬·원격 접속과 연결 오류 해결하기

MariaDB 강좌 / 로컬·원격 접속과 연결 오류 해결하기

로컬 TCP 연결을 명시하고 서버 정보·현재 계정·실제 테이블 권한을 확인합니다. 연결 거절·인증·DB 오류를 나누어 진단하고 원격 수신 주소·계정·TLS의 적용 조건을 설명합니다.

MariaDB 강좌 / 데이터베이스 만들기: CREATE DATABASE·USE·문자 집합

MariaDB 강좌 / 데이터베이스 만들기: CREATE DATABASE·USE·문자 집합

shopcourse 데이터베이스를 만들고 현재 연결의 작업 대상으로 선택합니다. utf8mb4와 collation, 기존 DB에서 IF NOT EXISTS의 한계, 권한·문자 설정 확인을 예제로 설명합니다.

MariaDB 강좌 / VIEW로 자주 쓰는 조회를 정의하기

MariaDB 강좌 / VIEW로 자주 쓰는 조회를 정의하기

CREATE VIEW로 결제 주문 합계를 정의하고 원본 변경·취소가 조회 결과에 반영되는지 확인합니다. CTE와의 차이, INVOKER·DEFINER 권한, 집계 뷰의 수정 제한과 정리 순서를 설명합니다.

MariaDB 강좌 / CASE로 조건별 값과 집계 만들기

MariaDB 강좌 / CASE로 조건별 값과 집계 만들기

CASE 조건의 순서와 ELSE를 상품 재고 상태로 실습합니다. SUM·COUNT 안의 조건부 집계, 0과 NULL의 차이, WHERE로 그룹을 없애는 경우와 0을 표시하는 경우를 설명합니다.

MariaDB 강좌 / 복제 구조와 지연·오류·장애 대응 이해하기

MariaDB 강좌 / 복제 구조와 지연·오류·장애 대응 이해하기

빈 두 서버를 준비하는 로컬 Compose 구성과 복제 상태·지연·오류 진단을 설명합니다. 적용 중지·재개를 관찰하고 백업과 장애 승격의 경계를 구분합니다.

MariaDB 강좌 / 기본키·AUTO_INCREMENT·UNIQUE로 행 식별하기

MariaDB 강좌 / 기본키·AUTO_INCREMENT·UNIQUE로 행 식별하기

기본키·자동 증가·고유 제약을 고객 데이터로 구분하고 중복 입력을 확인합니다. nullable UNIQUE, 복합 기본키와 트랜잭션 취소 후 자동 번호가 빠지는 경우를 실습합니다.

MariaDB / 샘플 데이터베이스 employees 설치하는 방법

MariaDB / 샘플 데이터베이스 employees 설치하는 방법

데이터베이스를 다루는 공부를 할 때 데이터가 들어있는 데이터베이스가 있으면 좋습니다. 데이터베이스를 직접 만드는 방법도 있지만, 공개된 샘플 데이터베이스를 이용하면 편합니다. 예를 들어 SQL Server라면 AdventureWorks라는 샘플 데이터베이스를 마이크로소프트에서 제공합니다. MariaDB라면 employees를 사용하면 됩니다.

MariaDB 강좌 / 두 연결로 격리 수준·잠금·교착 상태 확인하기

MariaDB 강좌 / 두 연결로 격리 수준·잠금·교착 상태 확인하기

별도 연결 A·B의 실행 순서대로 격리 수준, 행 잠금 대기와 교착 상태를 비교합니다. 초기화·재조회·오류 후 정리와 연결별 설정 복원까지 전체 코드로 확인합니다.

MariaDB 강좌 / 문자열 다루기: 연결·추출·치환·길이

MariaDB 강좌 / 문자열 다루기: 연결·추출·치환·길이

문자열 연결·추출·치환과 길이 계산을 상품 데이터로 실습합니다. NULL과 빈 문자열의 연결 차이, UTF-8 문자 수·바이트 수, 원본을 보존하며 가공 결과를 확인하는 기준을 설명합니다.