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 강좌 / 문자열 타입 선택하기: CHAR·VARCHAR·TEXT

MariaDB 강좌 / 문자열 타입 선택하기: CHAR·VARCHAR·TEXT

CHAR·VARCHAR·TEXT를 저장 목적에 따라 선택하고 문자 수·바이트 수·끝 공백을 비교합니다. 한글과 이모지 입력, 길이 초과 오류, 정렬 규칙과 긴 본문 저장 시 주의점을 설명합니다.

MariaDB 강좌 / GROUP BY·HAVING으로 묶고 집계 결과 걸러내기

MariaDB 강좌 / GROUP BY·HAVING으로 묶고 집계 결과 걸러내기

GROUP BY로 분류별 상품 수·재고·금액을 계산하고 HAVING으로 그룹을 제한합니다. WHERE 적용 시점과 비집계 열·SQL 모드·NULL 그룹의 주의점을 비교 실습으로 설명합니다.

MariaDB / VIEW

MariaDB / VIEW

VIEW는 가상의 테이블입니다. 실제로 데이터를 저장하지 않고, 기존의 하나 이상의 테이블을 기반으로 한 쿼리 결과를 테이블처럼 사용할 수 있게 해줍니다. 뷰는 복잡한 쿼리를 단순화하고, 보안 및 데이터 관리에 유용하게 사용됩니다.

MariaDB 강좌 / 사용자 계정 만들고 필요한 권한만 부여하기

MariaDB 강좌 / 사용자 계정 만들고 필요한 권한만 부여하기

사용자·호스트 조합을 확인하고 상품 한 테이블의 SELECT만 허용하는 계정을 만듭니다. 새 연결의 허용·거절 시험, 권한 회수와 기존 계정을 덮어쓰지 않는 정리 절차를 설명합니다.

MariaDB 강좌 / 최종 실습: 주문 데이터베이스 구축부터 권한·백업·복원까지

MariaDB 강좌 / 최종 실습: 주문 데이터베이스 구축부터 권한·백업·복원까지

주문 DB 구축·제한 계정·재고와 주문의 트랜잭션을 한 흐름으로 실습합니다. 확정 상태를 덤프해 별도 DB로 복원하고 행·금액·재고·키·권한 실패 조건으로 완성 여부를 검증합니다.

MariaDB 강좌 / 숫자 타입 선택하기: 정수·DECIMAL·부동소수점

MariaDB 강좌 / 숫자 타입 선택하기: 정수·DECIMAL·부동소수점

정수의 부호·범위, DECIMAL의 정밀도·반올림, FLOAT·DOUBLE의 근삿값 차이를 비교합니다. 같은 입력을 저장해 비교하고 범위 초과 오류와 경고를 확인하는 실습을 제공합니다.

MariaDB 강좌 / 숫자 계산과 타입 변환: ROUND·CAST

MariaDB 강좌 / 숫자 계산과 타입 변환: ROUND·CAST

ROUND와 CAST를 할인 금액·정확한 소수·숫자 문자열로 실습합니다. 반올림 시점, 앞자리 0 손실, 잘림 경고와 SQL 모드에 따른 저장 동작의 차이를 설명합니다.

MariaDB 강좌 / 첫 실습: 상품 테이블을 만들고 데이터를 넣어 조회하기

MariaDB 강좌 / 첫 실습: 상품 테이블을 만들고 데이터를 넣어 조회하기

상품 세 건을 저장하는 전체 SQL로 테이블 생성·입력·조회 과정을 실습합니다. 구조와 행 수, 가격·재고 조건의 예상 결과를 확인하고 반복 입력 오류와 실습 테이블 초기화 범위를 구분합니다.

MariaDB 강좌 / 서브쿼리·EXISTS·NOT EXISTS로 조건 표현하기

MariaDB 강좌 / 서브쿼리·EXISTS·NOT EXISTS로 조건 표현하기

평균값 서브쿼리와 EXISTS·NOT EXISTS를 상품·고객·주문으로 실습합니다. 한 값의 반환 조건, 상관 키 누락, paid 주문 부재의 정의와 NOT IN의 NULL 함정을 설명합니다.

MariaDB 강좌 / 백업을 별도 데이터베이스에 복원하고 검증하기

MariaDB 강좌 / 백업을 별도 데이터베이스에 복원하고 검증하기

새 원본과 별도 빈 DB를 준비해 덤프를 복원하고 객체·행 수·키·업무 합계를 비교합니다. 파일 안의 DB 전환·삭제 문장, 클라이언트 호환성과 부분 복원 실패의 대응을 설명합니다.