2026 SQLD SQL 실습 5 | 조인·행 수·미주문 고객 — 원본 표·쿼리·결과 풀이

데이터위자드 ·

2026 SQLD SQL 실습 5 | 조인·행 수·미주문 고객 — 원본 표·쿼리·결과 풀이

학습 실습 · 직접 따라 하기

이 글은 SQLD 개념을 직접 조회로 확인하는 SQL 학습 실습입니다. 아래 원본은 실제 서비스 자료와 분리된 연습 데이터이며, 각 문장은 WITH 절로 원본을 정의하므로 기존 테이블을 만들거나 수정할 필요가 없습니다.

수행 방식

컴퓨터에서 SELECT를 작성합니다. 객관식 선택 문제가 아닙니다. PostgreSQL 또는 SQLite3의 지원 버전에서 실습할 수 있습니다.

SQL 실습 파일 내려받기 (.sql)

원본 데이터

customers

idnameregion
1김하늘서울
2이바다부산
3박나래서울
4최새봄대전

orders

idcustomer_idamountstatusorder_date
1011100완료2026-10-31
1021200완료2026-11-01
1032150완료2026-11-02
104250취소2026-11-03
1053300완료2026-11-04
1063NULL대기2026-11-05
1071200완료2026-11-06
1082100완료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 c.name,o.id FROM customers c JOIN orders o ON o.customer_id=c.id ORDER BY o.id;
결과 1결과 2
김하늘101
김하늘102
이바다103
이바다104
박나래105
박나래106
김하늘107
이바다108

각 주문이 고객 한 명과 연결되어 8행입니다.

작업 2. 미주문 고객

주문이 전혀 없는 고객번호를 LEFT JOIN으로 찾으세요.

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 c.id FROM customers c LEFT JOIN orders o ON o.customer_id=c.id WHERE o.id IS NULL ORDER BY c.id;
결과 1
4

고객 4의 오른쪽 주문키가 NULL인 보완 행이 남습니다.

작업 3. 외부 조인 건수

모든 고객의 주문 건수를 구하세요.

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 c.id,COUNT(o.id) FROM customers c LEFT JOIN orders o ON o.customer_id=c.id GROUP BY c.id ORDER BY c.id;
결과 1결과 2
13
23
32
40

COUNT(o.id)는 실제 주문만 셉니다.

작업 4. COUNT(*) 함정

위 쿼리에서 COUNT(*)를 쓰면 결과를 비교하세요.

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 c.id,COUNT(*) FROM customers c LEFT JOIN orders o ON o.customer_id=c.id GROUP BY c.id ORDER BY c.id;
결과 1결과 2
13
23
32
41

고객 4도 보완 행이 하나여서 1입니다.

작업 5. 상태 ON 조건

완료 주문만 붙이면서 모든 고객의 건수를 구하세요.

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 c.id,COUNT(o.id) FROM customers c LEFT JOIN orders o ON o.customer_id=c.id AND o.status='완료' GROUP BY c.id ORDER BY c.id;
결과 1결과 2
13
22
31
40

오른쪽 상태를 ON에 두어 완료 주문이 없는 고객도 보존합니다.

작업 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 c.region,SUM(o.amount) FROM customers c JOIN orders o ON o.customer_id=c.id WHERE o.status='완료' GROUP BY c.region ORDER BY c.region;
결과 1결과 2
부산250
서울800

서울은 고객 1의 500과고객 3의 300으로 800입니다.

응용·반례 점검

  • 금액 200과 같은 동률 행을 추가했다고 가정하고 결과가 얼마나 늘지 설명합니다.
  • NULL을 0으로 바꾼 경우 COUNT·AVG가 달라지는지 확인합니다.
  • 정렬을 생략해도 지금 같은 순서가 나올 수 있지만 보장되는지 구분합니다.
  • 고객 4처럼 매칭 없는 기준 행을 남겨야 하는지 요구사항을 다시 읽습니다.

범위 확인

2026년 학습 범위를 기준으로 구성했습니다. 시험 시행기관의 자격 안내·출제 기준에서 과목과 변경 공지를 확인할 수 있습니다.

이전 · GROUP BY·HAVING·조건부 합계

다음 · 서브쿼리·EXISTS·NOT EXISTS

SQLD 전체 목차

과목별 이론

단원별 객관식

실습

필기 모의고사

예상 모의문제입니다.

스터디클럽의 다른 강의 보기