2026 SQLD SQL 실습 4 | GROUP BY·HAVING·조건부 합계 — 원본 표·쿼리·결과 풀이
데이터위자드 ·
학습 실습 · 직접 따라 하기
이 글은 SQLD 개념을 직접 조회로 확인하는 SQL 학습 실습입니다. 아래 원본은 실제 서비스 자료와 분리된 연습 데이터이며, 각 문장은 WITH 절로 원본을 정의하므로 기존 테이블을 만들거나 수정할 필요가 없습니다.
수행 방식
컴퓨터에서 SELECT를 작성합니다. 객관식 선택 문제가 아닙니다. PostgreSQL 또는 SQLite3의 지원 버전에서 실습할 수 있습니다.
원본 데이터
customers
| id | name | region |
|---|---|---|
| 1 | 김하늘 | 서울 |
| 2 | 이바다 | 부산 |
| 3 | 박나래 | 서울 |
| 4 | 최새봄 | 대전 |
orders
| id | customer_id | amount | status | order_date |
|---|---|---|---|---|
| 101 | 1 | 100 | 완료 | 2026-10-31 |
| 102 | 1 | 200 | 완료 | 2026-11-01 |
| 103 | 2 | 150 | 완료 | 2026-11-02 |
| 104 | 2 | 50 | 취소 | 2026-11-03 |
| 105 | 3 | 300 | 완료 | 2026-11-04 |
| 106 | 3 | NULL | 대기 | 2026-11-05 |
| 107 | 1 | 200 | 완료 | 2026-11-06 |
| 108 | 2 | 100 | 완료 | 2026-12-01 |
실행 순서
- SQL 파일의 WITH 정의와 한 개의 SELECT를 함께 선택해 실행합니다. WITH는 바로 뒤 한 문장에 적용됩니다.
- 먼저 정답을 보지 않고 요구한 열·행·정렬 기준을 작성합니다.
- 각 작업 아래의 결과 표와 행 수·NULL·합계를 비교합니다.
- 문자 비교의 정렬 규칙은 DBMS 설정에 따라 다를 수 있습니다. 이 실습은 명시한 이름과 값의 대응을 우선 확인합니다.
작업 1. 고객별 전체합
고객번호별 금액 합계를 구하세요.
SQL과 결과 표 확인
WITH customers(id,name,region) AS (VALUES (1,'김하늘','서울'),(2,'이바다','부산'),(3,'박나래','서울'),(4,'최새봄','대전')),
orders(id,customer_id,amount,status,order_date) AS (VALUES (101,1,100,'완료','2026-10-31'),(102,1,200,'완료','2026-11-01'),(103,2,150,'완료','2026-11-02'),(104,2,50,'취소','2026-11-03'),(105,3,300,'완료','2026-11-04'),(106,3,NULL,'대기','2026-11-05'),(107,1,200,'완료','2026-11-06'),(108,2,100,'완료','2026-12-01'))
SELECT customer_id,SUM(amount) FROM orders GROUP BY customer_id ORDER BY customer_id;| 결과 1 | 결과 2 |
|---|---|
| 1 | 500 |
| 2 | 300 |
| 3 | 300 |
고객 1=100+200+200,고객 2=150+50+100,고객 3=300입니다.
작업 2. 완료 금액만
완료 거래만 입력으로 사용해 고객별 합계를 구하세요.
SQL과 결과 표 확인
WITH customers(id,name,region) AS (VALUES (1,'김하늘','서울'),(2,'이바다','부산'),(3,'박나래','서울'),(4,'최새봄','대전')),
orders(id,customer_id,amount,status,order_date) AS (VALUES (101,1,100,'완료','2026-10-31'),(102,1,200,'완료','2026-11-01'),(103,2,150,'완료','2026-11-02'),(104,2,50,'취소','2026-11-03'),(105,3,300,'완료','2026-11-04'),(106,3,NULL,'대기','2026-11-05'),(107,1,200,'완료','2026-11-06'),(108,2,100,'완료','2026-12-01'))
SELECT customer_id,SUM(amount) FROM orders WHERE status='완료' GROUP BY customer_id ORDER BY customer_id;| 결과 1 | 결과 2 |
|---|---|
| 1 | 500 |
| 2 | 250 |
| 3 | 300 |
고객 2의 취소 50이 입력에서 제외되어 250입니다.
작업 3. 합계 조건
전체합이 400 이상인 고객만 남기세요.
SQL과 결과 표 확인
WITH customers(id,name,region) AS (VALUES (1,'김하늘','서울'),(2,'이바다','부산'),(3,'박나래','서울'),(4,'최새봄','대전')),
orders(id,customer_id,amount,status,order_date) AS (VALUES (101,1,100,'완료','2026-10-31'),(102,1,200,'완료','2026-11-01'),(103,2,150,'완료','2026-11-02'),(104,2,50,'취소','2026-11-03'),(105,3,300,'완료','2026-11-04'),(106,3,NULL,'대기','2026-11-05'),(107,1,200,'완료','2026-11-06'),(108,2,100,'완료','2026-12-01'))
SELECT customer_id,SUM(amount) FROM orders GROUP BY customer_id HAVING SUM(amount)>=400 ORDER BY customer_id;| 결과 1 | 결과 2 |
|---|---|
| 1 | 500 |
HAVING은 고객별 집계 뒤 합계를 검사합니다.
작업 4. 행 조건과 차이
개별 금액 200 이상인 거래만 합산해 고객별 결과를 구하세요.
SQL과 결과 표 확인
WITH customers(id,name,region) AS (VALUES (1,'김하늘','서울'),(2,'이바다','부산'),(3,'박나래','서울'),(4,'최새봄','대전')),
orders(id,customer_id,amount,status,order_date) AS (VALUES (101,1,100,'완료','2026-10-31'),(102,1,200,'완료','2026-11-01'),(103,2,150,'완료','2026-11-02'),(104,2,50,'취소','2026-11-03'),(105,3,300,'완료','2026-11-04'),(106,3,NULL,'대기','2026-11-05'),(107,1,200,'완료','2026-11-06'),(108,2,100,'완료','2026-12-01'))
SELECT customer_id,SUM(amount) FROM orders WHERE amount>=200 GROUP BY customer_id ORDER BY customer_id;| 결과 1 | 결과 2 |
|---|---|
| 1 | 400 |
| 3 | 300 |
고객 1의 100이 제외되어 합계 500이 아닌 400입니다.
작업 5. 두 상태 나란히
고객별 완료·취소 합계를 한 행에 표시하세요.
SQL과 결과 표 확인
WITH customers(id,name,region) AS (VALUES (1,'김하늘','서울'),(2,'이바다','부산'),(3,'박나래','서울'),(4,'최새봄','대전')),
orders(id,customer_id,amount,status,order_date) AS (VALUES (101,1,100,'완료','2026-10-31'),(102,1,200,'완료','2026-11-01'),(103,2,150,'완료','2026-11-02'),(104,2,50,'취소','2026-11-03'),(105,3,300,'완료','2026-11-04'),(106,3,NULL,'대기','2026-11-05'),(107,1,200,'완료','2026-11-06'),(108,2,100,'완료','2026-12-01'))
SELECT customer_id,SUM(CASE WHEN status='완료' THEN amount ELSE 0 END),SUM(CASE WHEN status='취소' THEN amount ELSE 0 END) FROM orders GROUP BY customer_id ORDER BY customer_id;| 결과 1 | 결과 2 | 결과 3 |
|---|---|---|
| 1 | 500 | 0 |
| 2 | 250 | 50 |
| 3 | 300 | 0 |
CASE로 집계 입력을 구분하고 SUM으로 각각 계산합니다.
작업 6. 고객별 건수
고객별 전체 주문 수와 금액 입력 수를 구하세요.
SQL과 결과 표 확인
WITH customers(id,name,region) AS (VALUES (1,'김하늘','서울'),(2,'이바다','부산'),(3,'박나래','서울'),(4,'최새봄','대전')),
orders(id,customer_id,amount,status,order_date) AS (VALUES (101,1,100,'완료','2026-10-31'),(102,1,200,'완료','2026-11-01'),(103,2,150,'완료','2026-11-02'),(104,2,50,'취소','2026-11-03'),(105,3,300,'완료','2026-11-04'),(106,3,NULL,'대기','2026-11-05'),(107,1,200,'완료','2026-11-06'),(108,2,100,'완료','2026-12-01'))
SELECT customer_id,COUNT(*),COUNT(amount) FROM orders GROUP BY customer_id ORDER BY customer_id;| 결과 1 | 결과 2 | 결과 3 |
|---|---|---|
| 1 | 3 | 3 |
| 2 | 3 | 3 |
| 3 | 2 | 1 |
고객 3은 주문 2건 중 금액이 있는 것은 1건입니다.
응용·반례 점검
- 금액 200과 같은 동률 행을 추가했다고 가정하고 결과가 얼마나 늘지 설명합니다.
- NULL을 0으로 바꾼 경우 COUNT·AVG가 달라지는지 확인합니다.
- 정렬을 생략해도 지금 같은 순서가 나올 수 있지만 보장되는지 구분합니다.
- 고객 4처럼 매칭 없는 기준 행을 남겨야 하는지 요구사항을 다시 읽습니다.
범위 확인
2026년 학습 범위를 기준으로 구성했습니다. 시험 시행기관의 자격 안내·출제 기준에서 과목과 변경 공지를 확인할 수 있습니다.
SQLD 전체 목차
과목별 이론
- 1과목 · 1장 1~3절 · 데이터 모델·엔터티·속성
- 1과목 · 1장 4~5절 · 관계·식별자와 카디널리티
- 1과목 · 2장 1~3절 · 정규화·조인·트랜잭션 모델
- 1과목 · 2장 4~5절 · NULL·본질식별자·인조식별자
- 2과목 · 1장 1~2절 · 관계형 DB와 SELECT·DISTINCT
- 2과목 · 1장 3절 · 문자·숫자 함수와 CASE
- 2과목 · 1장 4절 · WHERE·날짜 범위·연산자 우선순위
- 2과목 · 1장 5~6절 · 집계·GROUP BY·HAVING·ORDER BY
- 2과목 · 1장 7~8절 · INNER·OUTER·표준 조인
- 2과목 · 2장 1절 · 서브쿼리·EXISTS·스칼라 서브쿼리
- 2과목 · 2장 2~3절 · 집합 연산·ROLLUP·CUBE·GROUPING
- 2과목 · 2장 4~5절 · 윈도우 함수·순위·Top N
- 2과목 · 2장 6~8절 · 계층형 질의·셀프 조인·PIVOT·정규표현식
- 2과목 · 3장 1~2절 · DML·TCL과 트랜잭션
- 2과목 · 3장 3~4절 · DDL·DCL·제약조건·권한
단원별 객관식
- 1과목 · 1장 1~3절 · 데이터 모델·엔터티·속성
- 1과목 · 1장 4~5절 · 관계·식별자와 카디널리티
- 1과목 · 2장 1~3절 · 정규화·조인·트랜잭션 모델
- 1과목 · 2장 4~5절 · NULL·본질식별자·인조식별자
- 2과목 · 1장 1~2절 · 관계형 DB와 SELECT·DISTINCT
- 2과목 · 1장 3절 · 문자·숫자 함수와 CASE
- 2과목 · 1장 4절 · WHERE·날짜 범위·연산자 우선순위
- 2과목 · 1장 5~6절 · 집계·GROUP BY·HAVING·ORDER BY
- 2과목 · 1장 7~8절 · INNER·OUTER·표준 조인
- 2과목 · 2장 1절 · 서브쿼리·EXISTS·스칼라 서브쿼리
- 2과목 · 2장 2~3절 · 집합 연산·ROLLUP·CUBE·GROUPING
- 2과목 · 2장 4~5절 · 윈도우 함수·순위·Top N
- 2과목 · 2장 6~8절 · 계층형 질의·셀프 조인·PIVOT·정규표현식
- 2과목 · 3장 1~2절 · DML·TCL과 트랜잭션
- 2과목 · 3장 3~4절 · DDL·DCL·제약조건·권한
실습
- SQL 학습 실습 1 · 6작업 · SELECT·조건·정렬
- SQL 학습 실습 2 · 6작업 · NULL·COUNT·평균
- SQL 학습 실습 3 · 6작업 · 날짜 범위·문자 조건
- SQL 학습 실습 4 · 6작업 · GROUP BY·HAVING·조건부 합계
- SQL 학습 실습 5 · 6작업 · 조인·행 수·미주문 고객
- SQL 학습 실습 6 · 6작업 · 서브쿼리·EXISTS·NOT EXISTS
- SQL 학습 실습 7 · 6작업 · 순위·동률·고객별 Top N
- SQL 학습 실습 8 · 6작업 · 집합 연산·조건부 피벗·전체 검산
필기 모의고사
예상 모의문제입니다.