본 내용은 [멀티캠퍼스] 데이터 분석&데이터 엔지니어링 취업캠프 28회차에서 실시한 수업 내용 중 일부입니다.
교재 홍보 (본 과정의 SQL 교재)
교재 구매: https://www.yes24.com/Product/Goods/86544423
SQL로 맛보는 데이터 전처리 분석 - 예스24
SQL을 이용하여 현업에서 자주 사용되는 KPI 지표를 직접 추출해본다데이터 분석을 하기 위해서는 데이터베이스에 존재하는 데이터를 직접 추출할 수 있어야 한다. SQL은 우리가 데이터베이스에
www.yes24.com

ERD

위 3개 테이블에 주목
가정된 상황: 회사 업무 중 요청된 사항 처리하기
구매지표 추출
요청사항1: 매출액 조회
요청사항1-1: 일별 매출액 조회
일별 매출액을 조회하기 위해서는 주문일과 매출액 데이터가 필요하다.
주문일 데이터는 orders 테이블의 orderdate 컬럼이고,
매출액 데이터는 orderdetails 테이블의 quantityordered와 priceeach 컬럼을 참고하면 된다.
두 테이블을 연결하기 위해서는 JOIN 사용이 필요, 그 중에서 LEFT JOIN을 사용한다.
USE classicmodels; -- classicmodels DB 사용
SELECT
A.orderdate
, priceeach * quantityordered
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
;

해당 조회 결과는 건별로 매출이 발생한 결과이다. 일별 자료가 있긴하지면 데이터를 분석하기엔 모자르다.
따라서 일별로 종합된 데이터를 만들어야 한다.
이때 사용되는 것은 GROUP BY이다.
SELECT
A.orderdate
, SUM(priceeach * quantityordered) AS 매출액
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
GROUP BY 1
ORDER BY 1
;

집계함수인 SUM과 같이 사용하여 일별 매출액을 조회했다.
요청사항1-2; 월별 매출액 조회
월별로 조회 하기 위해서는 orderdate 컬럼에서 앞에서 7자리가 필요하다.
이를 위해 사용할 수 있는 함수로는 SUBSTR이 있다.
SUBSTR(컬럼, 시작위치, 길이)
사용 예시
SELECT SUBSTR('ABCDE', 2, 2);

위 문자열 'ABCDE'의 2번째 자리에서 2개의 문자열을 조회했다.
이를 orderdate 컬럼에 적용해보자.
SELECT
SUBSTR(A.orderdate, 1, 7) MM
, SUM(priceeach * quantityordered) AS 매출액
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
GROUP BY MM
ORDER BY MM
;

월별로 평균 매출액을 조회했다.
요청사항1-3: 연도별 매출액 조회
연도별은 4자리만 필요하다.
SELECT
SUBSTR(A.orderdate, 1, 4) YY
, SUM(priceeach * quantityordered) AS 매출액
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
GROUP BY YY
ORDER BY YY
;

연도별로 평균 매출액을 조회했다.
요청사항2: 일자별 구매자 수, 구매 건수
일자별은 orderdate 이용
구매자수는 custormernumber 이용
구매 건수는 ordernumber 이용
데이터 확인
SELECT
orderdate
, customernumber
, ordernumber
FROM orders;

한 고객이 하루에 여러 물건을 살 수 있다. 이때 단순히 COUNT()만 사용하면 한 고객이 여러번 집계된다.
따라서 중복을 제거해야한다.
구매 건수는 중복이 없을 것으로 생각되지만 같이 확인해보자.
SELECT
COUNT(DISTINCT customernumber) AS 구매자수
, COUNT(customernumber) AS 구매자수2
, COUNT(DISTINCT ordernumber) AS 구매건수
, COUNT( ordernumber) AS 구매건수2
FROM orders;

구매자 수는 중복이 있어 DISTINCT를 사용해야 한다.
구매 건수는 중복이 없어 그냥 사용해도 괜찮다.
일자별 구매자 수, 구매 건수 확인
SELECT
orderdate
, COUNT(DISTINCT customernumber) AS 구매자수
, COUNT(ordernumber) AS 구매건수
FROM orders
GROUP BY 1
ORDER BY 1
;

월별, 연도별은 SUBSTR()를 이용하면 구할 수 있다.
번외) 구매자수가 2명 이상인 날짜 확인
SELECT A.*
FROM (
SELECT
orderdate
, COUNT(DISTINCT customernumber) AS 구매자수
, COUNT(DISTINCT ordernumber) AS 구매건수
FROM orders
GROUP BY 1
ORDER BY 1
) A
WHERE A.구매자수 >= 2;

요청사항3: 연도별 인당 매출액
우선, 연도별 매출액과 구매자 수를 구한다.
매출액 = 개별가격(priceeach) x 주문수량(quantityordered)
SELECT
SUBSTR(A.orderdate, 1, 4) AS YY
, SUM(priceeach * quantityordered) AS 매출액
, COUNT(DISTINCT A.customernumber) AS 구매자수
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
GROUP BY 1
ORDER BY 1
;

인당 매출액 = 매출액 / 구매자 수
SELECT
SUBSTR(A.orderdate, 1, 4) AS YY
, COUNT(DISTINCT A.customernumber) AS 구매자수
, SUM(priceeach * quantityordered) AS 매출액
, SUM(priceeach * quantityordered) / COUNT(DISTINCT A.customernumber) AS AMV
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
GROUP BY 1
ORDER BY 1
;

번외) 인당 매출액이 4만 이상인 구매자수 조회
서브쿼리를 사용하여 WHERE절을 추가하여 조
SELECT *
FROM (
SELECT
SUBSTR(A.orderdate, 1, 7) AS MM
, COUNT(DISTINCT A.customernumber) AS 구매자수
, SUM(priceeach * quantityordered) AS 매출액
, SUM(priceeach * quantityordered) / COUNT(DISTINCT A.customernumber) AS AMV
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
GROUP BY 1
ORDER BY 1
) A
WHERE A.AMV >= 40000
;

요청사항4: 연도별 건당 구매 금액
인당 매출액과 유사
SELECT
SUBSTR(A.orderdate, 1, 4) YY
, COUNT(DISTINCT A.ordernumber) AS 구매건수
, SUM(priceeach * quantityordered) AS 매출액
, SUM(priceeach * quantityordered) / COUNT(DISTINCT A.ordernumber) AS ATV
FROM orders A
LEFT
JOIN orderdetails B
ON A.ordernumber = B.ordernumber
GROUP BY 1
;

'SQL' 카테고리의 다른 글
| [MySQL] SQL로 맛보는 데이터 전처리 분석(4-3) (2) | 2023.10.11 |
|---|---|
| [MySQL] SQL로 맛보는 데이터 전처리 분석(4-2) (0) | 2023.10.10 |
| [MySQL] SQL로 맛보는 데이터 전처리 분석(3) (0) | 2023.10.10 |
| [MySQL] SQL로 맛보는 데이터 전처리 분석(2-2) (2) | 2023.10.08 |
| [MySQL] SQL로 맛보는 데이터 전처리 분석(2-1) (0) | 2023.10.07 |