목차
10강 다면적인 축을 사용해 데이터 집약하기
상품의 카테고리, 가격 등을 조합해서 데이터의 특징을 추출해 리포팅하기
1) 카테고리별 매출과 소계 계산하기
카테고리의 소계와 총계를 한 번에 출력하려면, 계층별로 집계한 결과를 같은 컬럼(같은이름)이 되게 변환한 뒤, UNION ALL 구문으로 하나의 테이블로 합치면 됨.
** UNION ALL = 이름 같은 컬럼으로 구성된 두 개의 테이블 있을 때, 중복 데이터도 지우지 않고 모두 표시하여 합치는 방법 → but, 성능 안좋음.
—> ROLLUP 사용
** ROLLUP : 그룹화 및 집계를 수행, 부분합계와 총합계를 계산할 수 있음
ROLLUP 사용하면 소계를 계산할 때 레코드 집계 키가 NULL(합쳤을 때 이름이 지정 안되어있으니까) 이 되므로, COALESCE 함수로 NULL을 문자열 ‘all로 변환’
** COALESCE 함수 → parameter를 순차적으로 확인하여 앞에 값이 null이면 뒤에 값을 사용하고, 만약 해당값도 null이면, 그 뒤에 들어온 값을 사용한다.
#10-2 ROLLUP 사용해서 카테고리별 매출과 소계를 동시에 구하는 쿼리
SELECT
COALESCE(category, 'all') AS category
,COALESCE(sub_category, 'all') AS sub_category
,SUM(price) AS amount
FROM
purchase_detail_log
GROUP BY
ROLLUP(category, sub_category)
;
#실행결과
category | sub_category | amount
-----------------------------------
ladys_fashion | bag | 176000
ladys_fashion | jacket | 128000
ladys_fashion | all | 304000
mens_fashion | jacket | 147000
mens_fashion | shoes | 309000
mens_fashion | all | 456000
all | all | 760000
2) ABC 분석으로 잘 팔리는 상품 판별하기
ABC 분석 = 재고 관리 등에서 사용, 매출 중요도에 따라 상품을 나누고, 그에 맞게 전략을 만들 때 사용.
서비스의 매출이 어떻게 구성 되어 있는지 파악할 때 효과적임.
위에서 까만 선은 구성비 누계로 보면 됨.
일반적으로,
- A등급: 상위 0~70%
- B등급: 상위 70~90%
- C등급: 상위 90~1000%
데이터 작성하는 방법
- 매출이 높은 순서로 데이터 정렬
- 매출 합계를 집계
- 매출 합계를 기반으로 각 데이터가 차지하는 비율을 계산하고, 구성비를 구함.
- 계산한 카테고리의 구성비를 기반으로 구성비누계를 구함.
(카테고리의 매출과 해당시점까지의 누계를 따로 계산하고, 총 매출로 나누면 구성비 누계를 구할 수 있음.)
-원하는 시간에 있는 구매로그 압축 → 상품 카테고리마다 매출 계산 → 전체 매출에 대해 항목별 매출 구성비와 구성비누계를 계산 → 구성비누계를 기준으로 등급을 나눔
#10-3 매출 구성비누계와 ABC 등급을 계산하는 쿼리
WITH
monthly_sales AS(
SELECT
category
-- 항목별 매출 계산하기
, SUM(price) AS amount
FROM
purchase_detail_log
-- 대상 1개월 동안의 로그를 조건으로 걸기
WHERE
dt BETWEEN '2015-12-01' AND '2015-12-31'
GROUP BY
category
)
, sales_composition_ratio AS(
SELECT
category
,amount
-- 구성비: 100.0 *<항목별 매출> / <전체 매출>
, 100.0 * amount / SUM(amount) OVER() AS composition_ratop
-- 구성비누계 : 100.0 * <항목별 누계 매출> / <전체 매출>
, 100.0 * SUM(amount) OVER (ORDER BY amount DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
/ SUM(amount) OVER () cumulative_ratio
FROM
monthly_sales
)
SELECT
*
-- 구성비 누계 번위에 따라 순위 붙이기
, CASE
WHEN cumulative_ratio BETWEEN 0 AND 70 THEN 'A'
WHEN cumulative_ratio BETWEEN 70 AND 90 THEN 'B'
WHEN cumulative_ratio BETWEEN 90 AND 100 THEN 'C'
END AS abc_rank
FROM
sales_composition_ratio
ORDER BY
amount DESC
;
3) 팬 차트로 상품의 매출 증가율 확인하기
팬 차트
= 어떤 기준 시점을 100%로 두고, 이후의 숫자 변동을 확인할 수 있게 해주는 그래프.
작은 변화는 그래프에서 변화를 확인하기조차 힘들기 때문.
팬차트를 사용하면, 변화가 백분율로 표시되므로, 작은 변화도 쉽게 인지하고 상황을 판단할 수 있음. (변화 비율이 그래프에 표시되므로, 성장과 쇠퇴를 쉽게 파악할 수 있음.)
- 날짜 데이터를 기반으로 연과 월의 값 추출
- 연과 월 단위로 매출을 구함
- 구한 매출을 시계열 순서로 정렬
- 팬 차트 작성을 위한 기준이 되는 월 매출을 기준으로 비율을 구함.
(기준이 되는 매출이 시계열로 정렬했을 때 가장 첫 월의 매출일 때, FIRST_VALUE 윈도 함수 사용.)
#10-4 팬 차트 작성 때 필요한 데이터를 구하는 쿼리
WITH
daily_category_amount AS(
SELECT
dt
, category
, substring(dt,1,4) AS year
, substring(dt,6,2) AS year
, substring(dt,9,2) AS year
, SUM(price) AS amount
FROM purchase_detail_log
GROUP BY dt, category
)
, monthly_category_amount AS(
SELECT
concat(year,'-',month) AS year_month
, category
, SUM(amount) AS amount
FROM
daily_category_amount
GROUP BY
year,month, category
)
SELECT
year_month
, category
, amount
, FIRST_VALUE(amount)
OVER(PARTITION BY category ORDER BY year_month, category ROWS UNBOUNDED PRECEDING)
AS base_amount
,100.0
* amount
/ FIRST_VALUE(amount)
OVER(PARTITION BY category ORDER BY year_month, category ROWS UNBOUNDED PRECEDING)
AS rate
FROM monthly_category_amount
ORDER BY
year_month, category
;
** 어떤 시점에서의 매출 금액을 기준점으로 채택할 것인가 에 따라 성장 경향인지 쇠퇴 경향인지 판단이 크게 달라짐.
→ 계절 변동이 적은 평균적인 달을 기준으로 선택하는 것이 좋음. 근거를 가지고 기준점을 채택해야함.
4) 히스토그램으로 구매 가격대 집계하기
히스토그램
= 가로 축에 단계 (데이터의 범위), 세로 축에 도수(데이터의 개수)를 나타내는 그래프 → 데이터가 어떻게 분산되어 있는지 한눈에 확인 가능.
** 최빈값은 평균값과 비슷하지 않을 수도 있음.
- 히스토그램 만드는 방법
- 최댓값, 최솟값, 범위(최댓값-최솟값)를 구한다. → 첫시작과 마지막 지머
- 범위를 기반으로 몇 개의 계급으로 나눌지 결정하고, 각 계급의 하한과 상한(각각 어디부터 어디까지할지)을 구한다.
- 각 계급에 들어가는 데이터 개수(도수)를 구하고, 이를 표로 정리한다.
** 막대그래프와 차이점!
히스토그램은 각각의 막대 사이에 공백을 넣지 않음.
막대 그래프의 경우는 서로다른 항목을 나타내므로 중간에 공백을 넣지만,
히스토그램은 연속된 데이터의 분포를 확인하기 위해 사용하는 것이므로 공백을 넣지않고 그림.
- 임의의 계층 수로 히스토그램 만들기
# 10-8 히스토그램을 구하는 쿼리
WITH
stats AS(
SELECT
-- <금액의 최댓값> + 1 -> 모든 레코드가 지정한 범위 내부에 들어가기 위해서는 +1 해줘야함, 계급 판정 로직이 <계급 하한 이상> ~ <계급 상한 미만> 이기 때문에 최댓값이 11로 계산됨.
MAX(price) AS max_price
-- <금액의 최솟값> + 1
, MIN(price) AS min_price
-- 금액의 범위
, MAX(price) - MIN(price) AS range_price
-- 계층 수
, 10 AS bucket_num
FROM
purchase_detail_log
)
, purchase_log_with_bucket AS (
SELECT
price
, min_price
-- 정규화 금액 : 대상 금액에서 최소 금액을 뺀것
, price - min_price AS diff
-- 계층 범위 : 금액 범위를 계층 수로 나눈 것
, 1.0 * range_price / bucket_num AS bucket_range
-- 계층 판정 :
, with_bucket(price, min_price, max_price, bucket_num) AS bucket
FROM
purchase_detail_log, stats
)
SELECT
bucket
-- 계층의 하한과 상한 계산하기
, min_price + bucket_range * (bucket -1) AS lower_limit
, min_price + bucket_range * bucket AS upper_limit
-- 도수세기
, COUNT(price) AS num_purchase
-- 합계 금액 계사하기
, SUM(price) AS total_amount
FROM
purchase_log_with_bucket
GROUP BY
bucket, min_price, bucket_range
ORDER BY bucket
;
- 임의의 계층 너비로 히스토그램 작성하기
위에처럼 가격의 상한과 하한 기준으로도 최적의 범위를 구할 수 있지만, 소수점으로 계층을 구분한 리포트는 직감적이지 않아서,
금액의 최댓값, 최솟값, 금액 범위 등의 고정값을 기반으로 임의의 계층 너비로 변경할 수 있는 기능을 사용하기도 함.
50000 AS max_price, 0 AS min_price, 50000 AS range_price 이렇게 정해서! → 0 ~ 50000원의 범위를 10개의 계층으로 구분하는 쿼리.
→ 5,000원 단위로 구분된 계층 히스토그램 데이터.
- 히스토그램이 나누어진 경우
히스토그램 산이 2개로 나누어진 경우 서로 다른 모집단을 기반으로 하나의 데이터를 도출한 경우일수도 있음 ex) 성별 등등
→ 데이터에 여러 조건을 걸어 필터링해서 확인
'SQL' 카테고리의 다른 글
[데이터 분석을 위한 SQL 레시피] 12강 - 시계열에 따른 사용자 전체의 상태 변화 찾기 (1) | 2023.12.28 |
---|---|
[데이터 분석을 위한 SQL 레시피] 11강 - 사용자 전체의 특징과 경향 찾기 (0) | 2023.12.26 |
[데이터 분석을 위한 SQL 레시피] 9강 - 시계열 기반으로 데이터 집계하기 (0) | 2023.12.26 |
[데이터 분석을 위한 SQL 레시피] 8강 - 여러 개의 테이블 조작하기 (0) | 2023.12.26 |
[데이터 분석을 위한 SQL 레시피] 7강 -하나의 테이블에 대한 조작 (0) | 2023.12.26 |