참여인원
@강신웅 @김선경 @YERIM KIM @이종서 @hyohui Lee @저유비
사용 툴
WorkBench
| Tableau
| Google Spreadsheet
| Google Colaboratory
| Notion
Data Set 소개
1) 고객별 → 상품별 RFM 분석
data set 특성 상 상품의 판매 데이터 중심으로 이루어져있기 때문에 고객 데이터 분석이 아닌 상품별로 분석하여 RFM으로 진행
2) Recency 분석 관련
Recency 의 경우 ‘얼마나 최근에 구매했는가?’를 보아야하나 아래 표와 Classic 포함 모든 카테고리의 전체 데이터 Set 내의 pizza_type_id 별로 구분 시 대부분의 상품이 일별 최소 1회 주문량이 있음을 확인
SELECT date, COUNT(DISTINCT pizza_type_id)
FROM join_data
WHERE category = 'Classic'
GROUP BY date
ORDER BY date DESC;
따라서 일별 주문한 피자 종류는 대부분 8개로 얼마나 최근에 구매했는가에 대해 정의하기가 다소 어려움.
다만 메뉴별로 일일 주문량을 확인하니 아래 표와 같이 메뉴별로 주문수량에서의 차이가 있음을 확인
SELECT pizza_type_id, date, SUM(quantity)
FROM join_data
WHERE category = 'Classic'
GROUP BY pizza_type_id, date
ORDER BY date DESC;
상기 표와 이 일별 피자별 주문 건수는 피자 종류별 차이가 었으므로 Recency 를 pizza_type_id 별 재주문시간
의 평균 소요 시간(분)으로 계산하여 4분위로 나눠 백분율로 분배하여 구분하는 것으로 정의
| 카테고리 | 피자 종류 (수) | 매출액 ()
(매출액 / 피자종류) | 피자당 주문수 (건)
(주문수 / 피자종류) |
| --- | --- | --- | --- | --- | --- |
| 평균 | 8 | 204,465 | 12,394 | 26,204 | 1,582 |
| Supreme | 9 | 208,196 (25%) | 11,987 | 23,133 | 1,332 |
| Veggie | 9 | 193,690 (24%) | 11,649 | 21,521 | 1,294 |
| Classic | 8 | 220,052 (27%) | 14,888 | 27,507 | 1,861 |
| Chicken | 6 | 195,920 (24%) | 11,050 | 32,653 | 1,842 |
| 합계 | 32 | 817,858 | 49,574 | 104,814 | 6,329 |
-- Category별 피자당 매출액, 피자당 주문수 등 기본정보
SELECT category
, product
, sales
, quantity
, ROUND(sales / product) AS amt_per_pizza
, ROUND(quantity / product) AS cnt_per_pizza
FROM (
SELECT category
, COUNT(DISTINCT pizza_type_id) AS product
, ROUND(SUM(quantity*price)) AS sales
, SUM(quantity) quantity
FROM join_data
GROUP BY category
) AS a
ORDER BY product DESC, sales DESC;
2015년 피자가게 운영 결과, 전체 32가지 종류의 상품을 판매했으며 전체 매출액 $817,860을 기록.
카테고리 별 성과 비교 시, 가장 많은 매출을 올린 카테고리는 Classic 카테고리로 전체 매출의 27%를 차지.
가장 낮은 매출을 보인 군은 Chicken군으로 전체 매출의 24%를 차지. 다만 각 카테고리 별로 매출액 비중의 차이가 다소 미미.
* 피자 매출액 카테고리별 순위
Classic($220,052) > Supreme($208,196) > Chicken($195,920) > Veggie($193,690)
피자 상품 갯수의 경우 Supreme, Veggie가 각각 상품 9개로 가장 많은 메뉴를 취급하고 있으며 그 뒤로 Classic 8개, Chicken이 6개로 가장 적은 상품군을 취급함.
Veggie 군의 경우 가장 많은 상품군을 취급하나 매출은 가장 낮다는 특징을 보여 이에 가짓수를 줄여 성과가 준수한 상품에 리소스를 투여하는 방향이 필요.
* 피자 주문 횟수 카테고리별 순위 (주문횟수, 전체비중)
Classic(14,888회, 30%) > Supreme(11,987회, 24%) > Veggie(11,649회, 23%) > Chicken(11,050회, 22%)
2015년 전체 피자 주문은 49,574회 발생하여 일 평균 136건 정도의 주문이 들어옴.
카테고리 중 Classic 가장 많은 주문 횟수인 14,888회를 기록하여 일 평균 30회 정도의 주문이 들어와 전체 주문 횟수의 30% 정도의 비중을 차지함.
그 외 나머지 카테고리의 경우, Supreme, Veggie, Chicken 카테고리가 각각 전체 주문 횟수의 24%, 23%, 22% 비중을 차지하여 큰 차이를 보이지 않음
구분 | Classic | Supreme | Chicken | Veggie |
---|
순위 | 상품 타입 | 피자 종류 | 매출($) | 주문수(개) |
---|---|---|---|---|
1 | Chicken | thai_ckn | 43,434 | 2,371 |
2 | Chicken | bbq_ckn | 42,768 | 2,432 |
3 | Chicken | cali_ckn | 41,410 | 2,370 |
4 | Classic | classic_dlx | 38,180 | 2,453 |
5 | Supreme | spicy_ital | 34,831 | 1,924 |
6 | Chicken | southw_ckn | 34,706 | 1,917 |
7 | Supreme | ital_supr | 33,477 | 1,884 |
8 | Classic | hawaiian | 32,273 | 2,422 |
9 | Veggie | four_cheese | 32,266 | 1,902 |
10 | Supreme | sicilian | 30,940 | 1,938 |
SELECT category
, pizza_type_id
, ROUND(SUM(quantity * price)) sales
, SUM(quantity) qnt
FROM join_data
GROUP BY pizza_type_id, category
ORDER BY sales DESC
LIMIT 10;
* 상위 매출액 피자 상품 Top10 카테고리 별 비중
Chicken (4가지) > Supreme(3가지) > Classic (2가지) > Veggie(1가지)
* 피자 매출액 카테고리 별 순위
Chicken($220,052) > Supreme($208,196) > Chicken($195,920) > Veggie($193,690)
가장 높은 매출액을 보였던 Chicken 카테고리의 thai_ckn 상품은 매출 $43,434 기록하여 1위를 차지했으며 그 뒤로 bbq_ckn, cali_ckn 상품 순으로 모두 Chicken 카테고리가 상위 순위를 점하고 있었음
Chicken 카테고리는 다른 타 카테고리 대비 상품의 가짓수가 6가지로 가장 적으나 그 중 4가지의 상품이 모두 상위 10위를 차지해 개별 상품에 대한 고객의 선호도가 높다고 추측
Classic 카테고리의 경우 전체 상품 8개 중 2가지만 Top10을 차지, 다만 전체 카테고리의 매출액은 가장 높으므로 나머지 상품은 상위에는 들지 못했으나 타 카테고리 대비하여 주문 횟수 및 매출이 준수한 성과를 확보하고 있을 것이라 판단.
Veggie상품은 전체 상품 9가지 중 한가지 상품만 상위 10위에 듦. Veggie 카테고리의 경우 전체 성과 중 가장 낮은 매출을 보이고 있어 많은 상품을 취급하는 것보단 상품군을 좁혀 운영할 것을 추천
카테고리 | 1월 | 2월 | 3월 | 4월 | 5월 | 6월 | 7월 | 8월 | 9월 | 10월 | 11월 | 12월 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Chicken | 913 | 875 | 994 | 924 | 939 | 910 | 963 | 934 | 900 | 832 | 981 | 885 |
Classic | 1,257 | 1,178 | 1,236 | 1,253 | 1,324 | 1,199 | 1,331 | 1,283 | 1,202 | 1,181 | 1,262 | 1,182 |
Supreme | 1,044 | 964 | 991 | 1,013 | 1,045 | 1,040 | 1,041 | 991 | 877 | 998 | 1,050 | 933 |
Veggie | 1,018 | 944 | 1,040 | 961 | 1,020 | 958 | 1,057 | 960 | 911 | 872 | 973 | 935 |
합계 | 4,232 | 3,961 | 4,261 | 4,151 | 4,328 | 4,107 | 4,392 | 4,168 | 3,890 | 3,883 | 4,266 | 3,935 |
pizza_type_id | R | F | M | RFM | 상품 유형 | 특징 |
---|---|---|---|---|---|---|
hawaiian | 4 | 4 | 4 | 12 | 메인상품 | 주력으로 가져갈 수 있는 제품 |
classic_dlx | 4 | 4 | 4 | 12 | 메인상품 | 주력으로 가져갈 수 있는 제품 |
pepperoni | 4 | 3 | 2 | 9 | 충성상품 | 주문간격 및 주문빈도는 높아 충성도는 높으나 매출 비중이 적은 상품 |
고객들이 복수 주문하도록 유도 및 상품 프로모션을 통하여 매출액 증대 필요 | ||||||
big_meat | 3 | 3 | 1 | 7 | 충성상품 | 주문간격 및 주문빈도는 준수하나 매출 비중이 낮음 상품이 저렴하여 가성비 상품으로 포지셔닝 되어있으므로 타 상품과의 복수주문을 유도할 것을 추천 |
ital_cpcllo | 2 | 2 | 2 | 6 | 개선필요상품 | RFM 수치가 저조하여 주문의 빈도를 높여 매출액 및 주문간격을 높일 필요가 있음 |
napolitana | 1 | 2 | 2 | 5 | 개선필요상품 | 재주문시간이 특히 길어 마케팅 프로모션 및 1+1, 세트 주문으로 조합하여 개선이 필요 |
the_greek | 2 | 1 | 2 | 5 | 개선필요상품 | R>F. 약간의 규칙적 주문이 있으나 볼륨이 작음 |
pep_msh_pep | 1 | 1 | 1 | 3 | 개선필요상품 | 본 카테고리 상품 중 가장 저조한 RFM 수치 보이고 있으나, 타 카테고리의 상품 비교시 상대적으로 준수한 매출액 보이고 있으므로 고객들에게 제품 시식을 할 수 있도록 유도하는 것이 필요함 |
pizza_type_id | R | F | M | RFM | 상품 유형 | 특징 |
---|---|---|---|---|---|---|
ital_supr | 4 | 4 | 4 | 12 | 메인상품 | 카테고리 내 RFM 점수가 우수한 주력 상품. 성과 유지 필요 |
spicy_ital | 4 | 4 | 4 | 12 | 메인상품 | 카테고리 내 RFM 점수가 우수한 주력 상품. 성과 유지 필요 |
sicilian | 4 | 4 | 3 | 11 | 메인상품 | 상품의 충성도는 우수하나 매출 증대가 필요한 상품. |
peppr_salami | 3 | 3 | 3 | 9 | 메인상품 | 준수한 성과를 보이나 성과 하락 시 타입 변경 우려가 있음 |
prsc_argla | 3 | 3 | 2 | 8 | 잠재메인상품 | 재주문시간이 짧고 주문횟수는 많으나 매출 크기가 다소 작음 |
다른 피자와의 조합 및 옵션추가 은 마케팅 프로모션을 통한 매출 증대 필요 | ||||||
soppressata | 2 | 2 | 2 | 6 | 개선필요상품 | 재주문시간 및 주문횟수를 늘려 매출액 증대 도모해야하는 상품 |
calabrese | 2 | 2 | 1 | 5 | 개선필요상품 | 재주문시간 및 주문횟수를 늘려 매출액 증대 도모해야하는 상품 |
spinach_supr | 1 | 2 | 1 | 4 | 개선필요상품 | 해당 상품의 경우 타 상품과 함께 주문되는 경우가 많음 |
재주문 시간 및 주문횟수 늘려 매출액 증대 도모 | ||||||
brie_carre | 1 | 1 | 1 | 3 | 소비중지 | 제품 단종 제안 |
pizza_type_id | R | F | M | RFM | 상품 유형 | 특징 |
---|---|---|---|---|---|---|
thai_ckn | 4 | 3 | 4 | 11 | 메인상품 | Chicken 카테고리의 주력 상품 |
bbq_ckn | 4 | 3 | 4 | 11 | 메인상품 | Chicken 카테고리의 주력 상품 |
cali_ckn | 3 | 3 | 3 | 9 | 메인상품 | 준수한 성과를 보이나 특정 부분에서 성과가 떨어질 경우 타입이 변경될 우려가 있음 |
RFM 디벨롭을 통해 메인 상품으로 상향 필요 | ||||||
southw_ckn | 2 | 3 | 2 | 7 | 매니악상품 | 주문 횟수는 자주 발생하나 재주문시간 및 매출비중이 다소 작음 |
ckn_alfredo | 1 | 1 | 1 | 3 | 개선필요상품 | RFM 수치가 낮으나 사이드 식품이므로 세트 상품으로 전략을 노릴 수 있음 |
ckn_pesto | 1 | 1 | 1 | 3 | 개선필요상품 | RFM 수치가 낮으나 사이드 식품이므로 세트 상품으로 전략을 노릴 수 있음 |
피자명 | R | F | M | RFM | 상품유형 | 특징 |
---|---|---|---|---|---|---|
four_cheese | 4 | 4 | 4 | 12 | 메인상품 | 재주문시간, 주문 횟수, 매출액이 우수한 주력 상품. 지속적으로 성과 유지 필요 |
veggie_veg | 4 | 4 | 3 | 11 | 메인상품 | 재주문시간, 주문 횟수, 매출액이 우수한 주력 상품. 지속적으로 성과 유지 필요 |
mexicana | 3 | 4 | 4 | 11 | 메인상품 | 재주문시간, 주문 횟수, 매출액이 우수한 주력 상품. 지속적으로 성과 유지 필요 |
spinach_fet | 4 | 4 | 2 | 10 | 충성상품 | 매출량은 다소 떨어지나 재주문시간 및 주문건수가 우수, 충성도가 높아 up-selling 필요 |
five_cheese | 3 | 3 | 3 | 9 | 잠재메인상품 | RFM 이 준수한 성과를 보임, 지속적으로 관리 시 잠재적으로 메인 상품으로 상향 가능 |
green_garden | 2 | 2 | 1 | 5 | 개선필요상품 | 매출 저조, 다만 제품의 특성상 비건 및 베지터리안 타겟 공략 제안 |
+ 메인 상품과의 세트 조합을 통해 고객들에게 시식을 할 수 있도록 운영해볼 것을 제안 | ||||||
mediterraneo | 2 | 2 | 1 | 5 | 개선필요상품 | 매출 저조, 지중해식 상품으로 휴가시즌 단기간 운영하여 프로모션으로 활용해 볼 것을 제안 |
+ 메인 상품과의 세트 조합을 통해 고객들에게 시식을 할 수 있도록 운영해볼 것을 제안 | ||||||
ital_veggie | 1 | 2 | 2 | 5 | 개선필요상품 | 재주문시간 저조. 이탈리아식 상품으로 휴가시즌, 단기간 운영하여 프로모션으로 활용 제안 |
+ 메인 상품과의 세트 조합을 통해 고객들에게 시식을 할 수 있도록 운영해볼 것을 제안 | ||||||
spin_pesto | 1 | 2 | 1 | 4 | 단종제안 | Veggie 상품들 중 가장 낮은 RFM 수치 기록, 해당 상품 단종하여 타 상품에 매출 집중권장 |
전체 데이터 기간 | 2015-01-01 ~ 2015-12-31 |
---|---|
전체 피자 상품 갯수 | 32 |
총 주문 판매 피자수 (개) | 49,574 |
총 주문 횟수 (건) | 21,350 |
총 매출($) | 817,858 |
SELECT MIN(date) first_order
, MAX(date) last_order
, SUM(quantity) amount_orders
, COUNT(DISTINCT order_id) cnt_orders
, ROUND(SUM(quantity * price), 0) sales
FROM join_data;
-- 테이블 생성
CREATE TABLE pizza_types_1 (
pizza_type_id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255),
category VARCHAR(255),
ingredients VARCHAR(255)
);
-- pc 데이터 로드
load data local infile '/Users/w/Desktop/pizza_types.csv'
into table pizza_types_1
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(pizza_type_id, name, category, ingredients);
-- 테이블 병합
CREATE TABLE join_data AS
SELECT o1.order_id, o1.order_details_id, o1.pizza_id, o1.quantity, o2.date, o2.time, p1.pizza_type_id, p1.size, p1.price, p2.name, p2.category, p2.ingredients
FROM order_details o1
INNER JOIN orders o2
ON o1.order_id = o2.order_id
INNER JOIN pizzas p1
ON o1.pizza_id = p1.pizza_id
INNER JOIN pizza_types p2
ON p1.pizza_type_id = p2.pizza_type_id;
| category | 피자 종류 (수) | 매출액 ()
(매출액 / 피자종류) | 주문수 (개) | 피자당 주문수 (개)
(주문수 / 피자종류) |
| --- | --- | --- | --- | --- | --- |
| 평균 | 8 | 204,465 | 26,204 | 9,355 | 1,196 |
| Supreme | 9 | 208,196 (25%) | 23,133 | 9,085 | 1,009 |
| Veggie | 9 | 193,690 (24%) | 21,521 | 8,941 | 993 |
| Classic | 8 | 220,052 (27%) | 27,507 | 10,859 | 1,357 |
| Chicken | 6 | 195,920 (24%) | 32,653 | 8,536 | 1,423 |
| 합계 | 32 | 817,858 | - | 37,421 | 4,782 |
-- Category별 매출액, 주문수 등 기본정보
SELECT category
, product
, ROUND(sales, 0) AS sales
, ROUND(sales / product, 0) AS sales_per_product
, cnt_order
, ROUND(cnt_order / product, 0) AS cnt_per_product
FROM (
SELECT category
, ROUND(SUM(quantity*price), 2) AS sales
, ROUND(COUNT(DISTINCT pizza_type_id), 2) AS product
, COUNT(DISTINCT order_id) AS cnt_order
FROM join_data
GROUP BY category
) AS a
ORDER BY product DESC, sales DESC;
아래 기준으로 4분위로 구분하였으며, 단순 비교를 위해 임시로 가중치 모두 1로 가중치 설정
Frequency
Monetary
RFM 점수 분배표
Recency | Frequency | Monetary | 점수분배 |
---|---|---|---|
상위 25% | 상위 25% | 상위 25% | 4 |
상위 50% | 상위 50% | 상위 50% | 3 |
상위 75% | 상위 75% | 상위 75% | 2 |
상위 100% | 상위 100% | 상위 100% | 1 |
재주문시간
의 평균 소요 시간(분)으로 계산하여 4분위로 나누어 백분율로 분배하여 구분 (삭제)피자 이름 | 소요 시간(분) | 백분율 | R값 |
---|---|---|---|
classic_dlx | 76.8 | 0 | 4 |
hawaiian | 78.3 | 0.14 | 4 |
pepperoni | 78.3 | 0.14 | 4 |
big_meat | 95.3 | 0.43 | 3 |
ital_cpcllo | 106.1 | 0.57 | 2 |
the_greek | 112 | 0.71 | 2 |
napolitana | 113 | 0.86 | 1 |
pep_msh_pep | 116.6 | 1 | 1 |
WITH cnt_hour AS (
SELECT pizza_type_id
, TIMEDIFF(time, last_timestamp) AS timediff
FROM (
SELECT pizza_type_id
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM join_data
WHERE category = 'Classic'
) AS a
SELECT SEC_TO_TIME(SUM(timediff) / COUNT(timediff)) AS avg_reorder_time
FROM cnt_hour
-- 주문 간격 구하기
WITH timediff AS (
SELECT pizza_type_id
, date
, time
, last_timestamp
, TIMEDIFF(time, last_timestamp) AS time_diff -- 직전 주문과의 시간 간격
FROM (
SELECT pizza_type_id
, date
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM join_data
WHERE category = 'classic'
ORDER BY pizza_type_id, date, time
) AS last_timestamp
-- 재주문시간 구하기
), reorder_time AS (
SELECT pizza_type_id
, ROUND(AVG(TIME_TO_SEC(DATE_FORMAT(time_diff, '%H:%i:%s')) / 60),1) AS reorder_time
FROM timediff
GROUP BY pizza_type_id
ORDER BY reorder_time ASC
)
-- R값 구하기
SELECT pizza_type_id
, reorder_time
, ROUND(PERCENT_RANK() OVER (ORDER BY reorder_time), 2) AS R_percentage_classic
, CASE
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.25 THEN '4'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.5 THEN '3'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.75 THEN '2'
ELSE '1' END AS R_quartile_classic
FROM reorder_time;
2015년 전체 Classic 카테고리 피자 상품의 주문수량별 주문건수를 ‘백분율’로 4분위 구분하여 Frequency 분배
상품별 주문건수의 경우 classic_dlx, hawaiian, pepperoni 상품의 주문건수가 가장 많았으며, 해당 상품의 경우 Recency 내의 재주문시간 또한 상위에 포진해있는 상품이었음
상품 별로 classc_dlx, hawaiian, pepperoni 제품의 경우 Classic 그룹의 평균 일별 주문건수인 4.99건을 웃도는 수치를 보임
Classic 상품별 주문건수 및 Frequency 점수 분배
| 피자명 | 전체 주문수 | 일별 주문건수
(상품 주문건수 / 365) | 백분율 | F값 |
| --- | --- | --- | --- | --- |
| 합계 | 14,579 | 39.9 | - | - |
| classic_dlx | 2,416 | 6.62 | 1 | 4 |
| hawaiian | 2,370 | 6.49 | 0.86 | 4 |
| pepperoni | 2,369 | 6.49 | 0.71 | 3 |
| big_meat | 1,811 | 4.96 | 0.57 | 3 |
| napolitana | 1,451 | 3.98 | 0.43 | 2 |
| ital_cpcllo | 1,414 | 3.87 | 0.29 | 2 |
| the_greek | 1,406 | 3.85 | 0.14 | 1 |
| pep_msh_pep | 1,342 | 3.68 | 0 | 1 |
| 평균 | 1,822 | 4.99 | - | - |
쿼리
-- Classic 상품 별 주문수, 일별 주문수를 기준으로 백분율 4분위로 구분된 Frequency 값
SELECT pizza_type_id
, cnt
, ROUND((cnt/ 365), 2) avg_day
, ROUND(PERCENT_RANK() OVER (ORDER BY cnt), 2) AS F_percentage_classic
, CASE WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.75 THEN '3'
ELSE '4' END AS F_quartile_veggie
FROM (
SELECT pizza_type_id
, COUNT(DISTINCT order_details_id) AS cnt
FROM join_data
WHERE category = 'Classic'
GROUP BY pizza_type_id ) AS cnt_classic
ORDER BY cnt DESC;
Classic 부분의 Monetary 부분의 경우, 카테고리 상품의 매출액(price*quantity)의 평균을 4분위로 분배하여 점수 부여
2015년 전체 Classic 카테고리 피자 상품의 매출액은 총 $225,052로 전체 카테고리 상품 중 1위 차지하고 있으며 전체 상품의 평균 매출액 또한 $27,507로 2위차지하여 전체 카테고리에서 준수한 매출 성과를 보이고 있음
상품별로 비교시 Classic 상품 군 중 classic_dlx, hawaiian, pepperoni 상품이 상위 매출을 기록하고 있으며 본 상품의 경우 Recency, Frequency 점수 에서도 상위 랭킹을 차지하고 있음
하위 TOP3 매출의 경우 pep_mah_pep ($18,834) < big_meat ($22,968) < napolitana($24,087) 순으로 기록. 특히 가장 낮은 매출을 기록하고 있는 pep_mah_pep 상품의 경우, 매출 1위 상품과 비교시 매출액이 2배 이상 차이가 나며 해당 상품의 Frequancy 부분의 전체 주문 수 및 Recency 또한 성과가 저조함
전체 Classic 제품군의 경우 다른 타 카테고리 군 대비하여 매출 성과가 우수하나 지속적인 성과 확보를 위하여 하위 매출을 기록하는 pep_mah_pep 상품의 주문 빈도를 높일 필요가 있음, 이에 상위 매출인 classic_dlx, hawaiian, peppeoroni 제품과 세트로 판매하여 up-selling 전략을 세울것을 제안
Classic 카테고리 상품별 매출액
피자명 | 매출액($) / 매출비중(%) |
---|---|
합계 | 220,053 (100%) |
classic_dlx | 38,180 (17%) |
hawaiian | 32,273 (15%) |
pepperoni | 30,162 (14%) |
the_greek | 28,454 (13%) |
ital_cpcllo | 25,094 (11%) |
napolitana | 24,087 (11%) |
big_meat | 22,968 (10%) |
pep_msh_pep | 18,834 (9%) |
평균 | 27,507 |
-- 피자별 전체 매출
SELECT pizza_type_id
, ROUND(SUM(quantity*price), 0) AS sum_classic
FROM join_data
WHERE category = 'Classic'
GROUP BY pizza_type_id
ORDER BY sum_classic DESC;
Monetary
피자명 | 백분위 | M값 |
---|---|---|
classic_dlx | 1 | 4 |
hawaiian | 0.86 | 4 |
pepperoni | 0.71 | 3 |
the_greek | 0.57 | 3 |
ital_cpcllo | 0.43 | 2 |
napolitana | 0.29 | 2 |
big_meat | 0.14 | 1 |
pep_msh_pep | 0 | 1 |
쿼리
-- 피자별 매출 금액, 매출비중 (error), 주문수, 건당매출
SELECT pizza_type_id
, ROUND(PERCENT_RANK() OVER (ORDER BY sale), 2) AS Monetary_percentage_classic
, CASE WHEN PERCENT_RANK() OVER (ORDER BY sale) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY sale) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY sale) <= 0.75 THEN '3'
ELSE '4' END AS Monetary_quartile_classic
FROM (
SELECT pizza_type_id
, SUM(price * quantity) AS sale
FROM join_data
WHERE category = 'Classic'
GROUP BY pizza_type_id
) AS Monetary
ORDER BY Monetary_percentage_classic DESC;
RFM 점수 = a Recency 점수 + b Frequency 점수 + c * Monetary 점수(단순 비교를 위해 모두 1로 가중치 부여)
상품별 항목 구분 | Recency | Frequancy | Monetary |
---|---|---|---|
메인 상품 | 상 | 상 | 상 |
충성 상품 | 상 | 상 | 하 |
잠재 충성 상품 | 상 | 하 | 상 |
잠재 메인 상품 | 하 | 상 | 상 |
매니악 상품 | 하 | 상 | 하 |
고가 상품 | 하 | 하 | 상 |
개선필요상품 | 하 | 하 | 하 |
pizza_type_id | R | F | M | RFM | 상품 유형 | 특징 |
---|---|---|---|---|---|---|
hawaiian | 4 | 4 | 4 | 12 | 메인상품 | 주력으로 가져갈 수 있는 제품 |
classic_dlx | 4 | 4 | 4 | 12 | 메인상품 | 주력으로 가져갈 수 있는 제품 |
pepperoni | 4 | 3 | 2 | 9 | 충성상품 | 주문간격 및 주문빈도는 높아 충성도는 높으나 매출 비중이 적은 상품 |
고객들이 복수주문하도록 유도 및 상품 프로모션을 통하여 매출액 증대 필요 | ||||||
big_meat | 3 | 3 | 1 | 7 | 충성상품 | 주문간격 및 주문빈도는 준수하나 매출 비중이 낮음 상품이 저렴하여 가성비 상품으로 포지셔닝 되어있으므로 타 상품과의 복수주문을 유도할 것을 추천 |
ital_cpcllo | 2 | 2 | 2 | 6 | 개선필요상품 | RFM 수치가 저조하여 주문의 빈도를 높여 매출액 및 주문간격을 높일 필요가 있음 |
napolitana | 1 | 2 | 2 | 5 | 개선필요상품 | 재주문시간이 특히 길어 마케팅 프로모션 및 1+1, 세트 주문으로 조합하여 개선이 필요 |
the_greek | 2 | 1 | 2 | 5 | 개선필요상품 | R>F. 약간의 규칙적 주문이 있으나 볼륨이 작음 |
pep_msh_pep | 1 | 1 | 1 | 3 | 개선필요상품 | 본 카테고리 상품 중 가장 저조한 RFM 수치 보이고 있으나, 타 카테고리의 상품 비교시 상대적으로 준수한 매출액 보이고 있으므로 고객들에게 제품 시식을 할 수 있도록 유도하는 것이 필요함 |
[주력상품이므로 지속적인 매출확보를 위한 액션 필요]
충성상품
: pepperoni, big_meat
[제품의 충성도는 높으나 매출액 성과가 저조, 이에 매출 증가를 위한 전략 필요]
개선필요상품
: ital_cpcllo, napolitana, the_greek, pep_msh_pep
[RFM 점수 내에서 하나 이상 2점 대 상품]
[RFM 점수가 모두 *1점대인 상품 : pep_msh_pep]*
| category | 피자 종류 (수) | 매출액 ()
(매출액 / 피자종류) | 주문수 (건) | 피자당 주문수 (개)
(주문수 / 피자종류) |
| --- | --- | --- | --- | --- | --- |
| Supreme | 9 | 208,196 | 23,133 | 9,085 | 1,009 |
| Veggie | 9 | 193,690 | 21,521 | 8,941 | 993 |
| Classic | 8 | 220,052 | 27,507 | 10,859 | 1,357 |
| Chicken | 6 | 195,920 | 32,653 | 8,536 | 1,423 |
| 합계 | 32 | 817,858 | 25,558 | 37,421 | 1,169 |
-- Category로 매출액, 주문수 등
SELECT category
, product
, ROUND(sales, 0) AS sales
, ROUND(sales / product, 0) AS sales_per_product
, cnt_order
, ROUND(cnt_order / product, 0) AS cnt_per_product
FROM (
SELECT category
, ROUND(SUM(quantity*price), 2) AS sales
, ROUND(COUNT(DISTINCT pizza_type_id), 2) AS product
, COUNT(DISTINCT order_id) AS cnt_order
FROM join_data
GROUP BY category
) AS a
ORDER BY product DESC, sales DESC;
아래 기준으로 4분위로 구분하였으며, 단순 비교를 위해 임시로 가중치 모두 1로 설정
Frequency
Monetary
Recency | Frequency | Monetary | 점수분배 |
---|---|---|---|
상위 25% | 상위 25% | 상위 25% | 4 |
상위 50% | 상위 50% | 상위 50% | 3 |
상위 75% | 상위 75% | 상위 75% | 2 |
상위 100% | 상위 100% | 상위 100% | 1 |
피자명 | 재주문시간(분) | 백분율 | R값 |
---|---|---|---|
sicilian | 91.6 | 0 | 4 |
ital_supr | 94.1 | 0.12 | 4 |
spicy_ital | 94.7 | 0.25 | 4 |
peppr_salami | 110.9 | 0.38 | 3 |
prsc_argla | 113.5 | 0.5 | 3 |
spinach_supr | 138 | 0.62 | 2 |
soppressata | 138.9 | 0.75 | 2 |
calabrese | 140.3 | 0.88 | 1 |
brie_carre | 169.9 | 1 | 1 |
WITH cnt_hour AS (
SELECT pizza_type_id
, TIMEDIFF(time, last_timestamp) AS timediff
FROM (
SELECT pizza_type_id
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM join_data
WHERE category = 'Supreme'
) AS a
SELECT SEC_TO_TIME(SUM(timediff) / COUNT(timediff)) AS avg_reorder_time
FROM cnt_hour
-- 주문 간격 구하기
WITH timediff AS (
SELECT pizza_type_id
, date
, time
, last_timestamp
, TIMEDIFF(time, last_timestamp) AS time_diff -- 직전 주문과의 시간 간격
FROM (
SELECT pizza_type_id
, date
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM join_data
WHERE category = 'Supreme'
ORDER BY pizza_type_id, date, time
) AS last_timestamp
-- 재주문시간 구하기
), reorder_time AS (
SELECT pizza_type_id
, ROUND(AVG(TIME_TO_SEC(DATE_FORMAT(time_diff, '%H:%i:%s')) / 60),1) AS reorder_time
FROM timediff
GROUP BY pizza_type_id
ORDER BY reorder_time ASC
)
-- R값 구하기
SELECT pizza_type_id
, reorder_time
, ROUND(PERCENT_RANK() OVER (ORDER BY reorder_time), 2) AS R_percentage_supreme
, CASE
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.25 THEN '4'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.5 THEN '3'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.75 THEN '2'
ELSE '1' END AS R_quartile_supreme
FROM reorder_time;
-- Supreme 상품 별 주문수, 일별 주문수를 기준으로 백분율 4분위로 구분된 Frequency 값
SELECT pizza_type_id
, cnt
, ROUND((cnt/ 365), 2) avg_day
, ROUND(PERCENT_RANK() OVER (ORDER BY cnt), 2) AS F_percentage_classic
, CASE WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.75 THEN '3'
ELSE '4' END AS F_quartile_veggie
FROM (
SELECT pizza_type_id
, COUNT(DISTINCT order_details_id) AS cnt
FROM join_data
WHERE category = 'Supreme'
GROUP BY pizza_type_id ) AS cnt_classic
ORDER BY cnt DESC;
Supreme 부분 Monetary의 경우 카테고리 각 상품의 매출액(price*quantity)의 평균을 4분위로 분배하여 점수 부여
본 카테고리의 경우 9가지의 상품을 제공하고 있으며 2015년 간 전체 매출액 $208,196 기록하여 전체 카테고리 중 두번째로 높은 매출 기록
전체 상품 중 spicy_ital 피자가 $34,831 매출액 기록하여 Supreme 전체 매출의 17% 차지해 가장 높은 매출을 보였으며 그 뒤로 ital_supr($33,477) > sicilian($30,940) 가 그 뒤를 이음
그 뒤를 잇는 peppr_salami 및 prsc_argal 상품은 앞서 상품 대비 매출 감소폭이 커졌으나 평균 매출액 대비 여전히 소폭 높은 매출을 보여 해당 상품의 경우 상품 조합을 통한 up-selling 혹은 마케팅 프로모션을 통한 매출량을 증대 시킬 수 있는 방안이 필요
그 아래로 soppressata, calabrese, spinach_supr, brie_carre 상품의 매출의 경우 매출 감소 폭이 4% 이상으로 두드려졌으며 각 상품이 Supreme 카테고리 전체 매출액의 10% 미만을 차지
특히 brie_carre 상품의 경우 전체 Supreme 매출액의 6% 차지 및 평균 매출액의 절반 수준이 되지 않음. 해당 상품의 경우 재주문시간도 늦으며 일당 평균 주문 건수가 1.3회로 타 상품 대비 저조한 성과를 보여 Supreme 군의 성격상 맞지 않아 단종할 것을 제안드림
Supreme 피자별 상품별 매출액
피자명 | 매출액($) | 비중 |
---|---|---|
Supreme 전체 상품 매출액 평균 | 23,133 | - |
spicy_ital | 34,831 | 17% |
ital_supr | 33,477 | 16% |
sicilian | 30,940 | 15% |
peppr_salami | 25,529 | 12% |
prsc_argla | 24,193 | 12% |
soppressata | 16,426 | 8% |
calabrese | 15,934 | 8% |
spinach_supr | 15,278 | 7% |
brie_carre | 11,588 | 6% |
합계 | 208,196 | 100% |
쿼리
SELECT pizza_type_id
, ROUND(SUM(quantity*price), 0) AS sum_supreme
FROM join_data
WHERE category = 'Supreme'
GROUP BY pizza_type_id
ORDER BY sum_supreme DESC;
Monetary
피자명 | 백분율 | M값 |
---|---|---|
spicy_ital | 1 | 4 |
ital_supr | 0.88 | 4 |
sicilian | 0.75 | 3 |
peppr_salami | 0.62 | 3 |
prsc_argla | 0.5 | 2 |
soppressata | 0.38 | 2 |
calabrese | 0.25 | 1 |
spinach_supr | 0.12 | 1 |
brie_carre | 0 | 1 |
쿼리
-- 피자별 매출 금액, 일평균 매출
SELECT pizza_type_id
, sum_sale
, avg_sale
, ROUND(PERCENT_RANK() OVER (ORDER BY avg_sale), 2) AS Monetary_percentage_veggie
, CASE WHEN PERCENT_RANK() OVER (ORDER BY avg_sale) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY avg_sale) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY avg_sale) <= 0.75 THEN '3'
ELSE '4' END AS Monetary_quartile_veggie
FROM (
SELECT pizza_type_id
, ROUND(SUM(price * quantity), 0) AS sum_sale
, ROUND(SUM(price * quantity)/ 365, 0) AS avg_sale
FROM join_data
WHERE category = 'Supreme'
GROUP BY pizza_type_id
) AS sale
ORDER BY Monetary_percentage_veggie DESC
RFM 점수 = a Recency 점수 + b Frequency 점수 + c * Monetary 점수(단순 비교를 위해 모두 1로 가중치 부여)
상품별 항목 구분 | Recency | Frequancy | Monetary |
---|---|---|---|
메인 상품 | 상 | 상 | 상 |
충성 상품 | 상 | 상 | 하 |
잠재 충성 상품 | 상 | 하 | 상 |
잠재 메인 상품 | 하 | 상 | 상 |
매니악 상품 | 하 | 상 | 하 |
고가 상품 | 하 | 하 | 상 |
| 개선필요상품 &
소비 중지 (Dormant) | 하 | 하 | 하 |
pizza_type_id | R | F | M | RFM | 상품 유형 | 특징 |
---|---|---|---|---|---|---|
ital_supr | 4 | 4 | 4 | 12 | 메인상품 | 카테고리 내 RFM 점수가 우수한 주력 상품. 성과 유지 필요 |
spicy_ital | 4 | 4 | 4 | 12 | 메인상품 | 카테고리 내 RFM 점수가 우수한 주력 상품. 성과 유지 필요 |
sicilian | 4 | 4 | 3 | 11 | 메인상품 | 상품의 충성도는 우수하나 매출 증대가 필요한 상품. |
peppr_salami | 3 | 3 | 3 | 9 | 메인상품 | 준수한 성과를 보이나 성과 하락 시 타입 변경 우려가 있음 |
prsc_argla | 3 | 3 | 2 | 8 | 잠재메인상품 | 재주문시간이 짧고 주문횟수는 많으나 매출 크기가 다소 작음 |
다른 피자와의 조합 및 옵션추가 은 마케팅 프로모션을 통한 매출 증대 필요 | ||||||
soppressata | 2 | 2 | 2 | 6 | 개선필요상품 | 재주문시간 및 주문횟수를 늘려 매출액 증대 도모해야하는 상품 |
calabrese | 2 | 1 | 1 | 5 | 개선필요상품 | 재주문시간 및 주문횟수를 늘려 매출액 증대 도모해야하는 상품 |
spinach_supr | 1 | 2 | 1 | 4 | 개선필요상품 | 해당 상품의 경우 타 상품과 함께 주문되는 경우가 많음 |
재주문 시간 및 주문횟수 늘려 매출액 증대 도모 | ||||||
brie_carre | 1 | 1 | 1 | 3 | 소비중지 | 제품 단종 제안 |
[주력상품이므로 지속적인 매출확보를 위한 액션 필요]
잠재메인상품
: prsc_argla
[재주문시간이 짧고 주문 횟수는 많으나 매출의 크기가 다소 작음. 매출 관리를 통해 메인 상품으로 상향이 필요]
개선필요상품
: soppressata, calabrese, spinach_supr
[ RFM 부분의 점수가 모두 2점대인 상품 : soppressata ]
[ RFM 점수 중 한개 이상 부분에서 1점대인 상품 : calabrese, spinach_supr ]
소비중지
: brie_carre
[RFM 점수가 저조하여 단종 제안 상품]
-- Category로 매출액, 주문수 등
SELECT category
, product
, ROUND(sales, 0) AS sales
, ROUND(sales / product, 0) AS sales_per_product
, cnt_order
, ROUND(cnt_order / product, 0) AS cnt_per_product
FROM (
SELECT category
, ROUND(SUM(quantity*price), 2) AS sales
, ROUND(COUNT(DISTINCT pizza_type_id), 2) AS product
, COUNT(DISTINCT order_id) AS cnt_order
FROM join_data
GROUP BY category
) AS a
ORDER BY product DESC, sales DESC;
| category | 피자 종류 | 매출액 ()
(매출액 / 피자종류) | 주문수 (개) | 피자당 주문수 (개)
(주문수 / 피자종류) |
| --- | --- | --- | --- | --- | --- |
| 평균 | 8 | 204,465 | 26,203.5 | 9,355.25 | 1,195.5 |
| Supreme | 9 | 208,196 | 23,133 | 9,085 | 1,009 |
| Veggie | 9 | 193,690 | 21,521 | 8,941 | 993 |
| Classic | 8 | 220,052 | 27,507 | 10,859 | 1,357 |
| Chicken | 6 | 195,920 | 32,653 | 8,536 | 1,423 |
| 합계 | 32 | 817,858 | - | 37,421 | 4,782 |
상품 별 재주문시간 간격, 상품 별 주문횟수, 상품 별 매출금액을 기준으로 4분위값 부여
아래 기준으로 4분위로 구분하였으며, 단순 비교를 위해 임시로 가중치 모두 1로 설정
Recency
Frequency
Monetary
RFM 점수 분배표
Recency | Frequency | Monetary | 점수분배 |
---|---|---|---|
상위 25% | 상위 25% | 상위 25% | 4 |
상위 50% | 상위 50% | 상위 50% | 3 |
상위 75% | 상위 75% | 상위 75% | 2 |
상위 100% | 상위 100% | 상위 100% | 1 |
피자명 | 재주문시간(s) | 소요 시간(분) | 백분율 | R값 |
---|---|---|---|---|
bbq_ckn | 4,744.2691 | 79분 | 0.00 | 4 |
cali_ckn | 4,775.7649 | 79분 | 0.20 | 4 |
thai_ckn | 4,799.3158 | 80분 | 0.40 | 3 |
southw_ckn | 5,519.6545 | 91분 | 0.60 | 2 |
ckn_alfredo | 8,069.3733 | 134분 | 0.80 | 1 |
ckn_pesto | 8,241.4819 | 137분 | 1.00 | 1 |
WITH cnt_hour AS (
SELECT pizza_type_id,
TIME_TO_SEC(timediff(time, last_timestamp)) AS diff_seconds
FROM (
SELECT pizza_type_id,
time,
LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM order_pizza
WHERE category = 'Chicken'
) AS a
)
SELECT SEC_TO_TIME(SUM(diff_seconds) / COUNT(diff_seconds)) AS avg_reorder_time
FROM cnt_hour;
-- Recency
WITH a AS (
SELECT pizza_type_id
, date
, time
, last_timestamp
, TIMEDIFF(time, last_timestamp) AS time_diff
FROM (
SELECT pizza_type_id
, date
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM order_pizza
WHERE category = 'Chicken'
ORDER BY pizza_type_id, date, time
) AS last_timestamp
), b AS (
SELECT pizza_type_id
, AVG(TIME_TO_SEC(DATE_FORMAT(time_diff, '%H:%i:%s'))) AS reorder_time
FROM a
GROUP BY pizza_type_id
ORDER BY reorder_time ASC
)
SELECT pizza_type_id
, reorder_time
, ROUND(PERCENT_RANK() OVER (ORDER BY reorder_time), 2) AS R_percentage_chicken
, CASE WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.25 THEN '4'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.5 THEN '3'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.75 THEN '2'
ELSE '1' END AS R_quartile_chicken
FROM b
/* 수정 (from.신웅).
1. 테이블 변경: order_pizza > join_data
2. 단위: 초 > 분
3. 소수점: 4자리 > 1자리
*/
WITH a AS (
SELECT pizza_type_id
, date
, time
, last_timestamp
, TIMEDIFF(time, last_timestamp) AS time_diff
FROM (
SELECT pizza_type_id
, date
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM join_data
WHERE category = 'Chicken'
ORDER BY pizza_type_id, date, time
) AS last_timestamp
), b AS (
SELECT pizza_type_id
, ROUND(AVG(TIME_TO_SEC(DATE_FORMAT(time_diff, '%H:%i:%s')))/60, 1) AS reorder_time
FROM a
GROUP BY pizza_type_id
ORDER BY reorder_time ASC
)
SELECT pizza_type_id
, reorder_time
, ROUND(PERCENT_RANK() OVER (ORDER BY reorder_time), 2) AS R_percentage_chicken
, CASE WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.25 THEN '4'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.5 THEN '3'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.75 THEN '2'
ELSE '1' END AS R_quartile_chicken
FROM b;
2015년 전체 Chicken 카테고리 피자 상품의 주문수량별 주문건수를 ‘백분율’로 4분위 구분하여 Frequency 분배
Chicken 카테고리 상품 별 전체 주문 수 비교시 bbq_ckn(2,372건) > thai_ckn(2,315건) > cali_ckn(2,302건) 순으로 주문건수가 가장 많았으며 일별 주문건수 또한 6건 이상으로 평균 주문건수를 웃도는 수치를 기록함
하위 주문건수를 기록한 상품의 경우 특히 ckn_pesto(961건) < ckn_alfredo(980건) 순으로 가장 낮았으며 따라서 일 평균 주문 건수 또한 2.68건, 2.63건으로 Chicken 카테고리의 일 평균 주문 건수인 4.94건을 밑도는 수치를 기록
하위 주문 건수를 기록한 ckn_pesto, ckn_alfredo 상품의 경우 Recency 부분의 재주문시간도 저조 하였으므로 주문수를 높일 수 있는 방법이 필요.
ckn_pesto, ckn_alfredo 상품의 경우 피자가 아닌 파스타 제품으로 사이드 메뉴의 성격이 강함. 이에 주문수를 높이기 위하여 사이드 메뉴가 포함된 세트메뉴로 운영하여 주문 수를 상향 시켜볼 것을 제안
Chicken 상품별 주문건수 및 Frequency 점수 분배
| 피자명 | 전체 주문수 | 일별 주문건수
(상품 주문건수 / 365) | 백분율 | F값 |
| --- | --- | --- | --- | --- |
| 합계 | 10,815 | 29.64 | - | - |
| bbq_ckn | 2,372 | 6.50 | 1 | 4 |
| thai_ckn | 2,315 | 6.34 | 0.8 | 4 |
| cali_ckn | 2,302 | 6.31 | 0.6 | 3 |
| southw_ckn | 1,885 | 5.16 | 0.4 | 2 |
| ckn_alfredo | 980 | 2.68 | 0.2 | 1 |
| ckn_pesto | 961 | 2.63 | 0 | 1 |
| 평균 | 1,803 | 4.94 | - | - |
쿼리
- Chicken 상품 별 주문수, 일별 주문수를 기준으로 백분율 4분위로 구분된 Frequency 값
SELECT pizza_type_id
, cnt
, ROUND((cnt/ 365), 2) avg_day
, ROUND(PERCENT_RANK() OVER (ORDER BY cnt), 2) AS F_percentage_Chicken
, CASE WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.75 THEN '3'
ELSE '4' END AS F_quartile_Chicken
FROM (
SELECT pizza_type_id
, COUNT(DISTINCT order_details_id) AS cnt
FROM join_data
WHERE category = 'Chicken'
GROUP BY pizza_type_id ) AS cnt_Chicken
ORDER BY cnt DESC;
2015년 전체 Chicken 카테고리 상품의 상품별 매출액(price*quantity)의 일평균 값을 4분위하여 Monetary 점수 부여
2015년 전체 Chicken 카테고리의 전체 상품의 매출액은 $195,920이며 Classic, Supreme 카테고리에 이어 3번째 매출 순위 기록
Chicken 카테고리의 평균 매출액은 $32,653 이며 thai_ckn > bbq_ckn > cali_ckn > southw_ckn 상품은 평균을 상회하는 매출액 기록
하위 매출액을 기록한 ckn_alfredo, ckn_pesto 제품은 평균 매출액의 약 2배 이하의 매출을 기록, 두 상품의 경우 전체 매출 비중 또한 9% 기록하여 한자리 수의 매출 비중을 보임
다만 두 상품의 경우 파스타 계열이므로 본 메뉴인 피자보다는 사이드 메뉴의 성격이 강하며, 두 상품의 매출을 합했을 경우 전체 18%의 매출 비중을 가져가기 때문에 단종 보다는 주문빈도 및 매출량을 늘릴 것을 제안드림
Chicken 카테고리 상품별 매출액
피자명 | 매출액($) / 매출비중(%) |
---|---|
합계 | 195,920 (100%) |
thai_ckn | 43,434 (22%) |
bbq_ckn | 42,768 (22%) |
cali_ckn | 41,410 (21%) |
southw_ckn | 34,706 (18%) |
ckn_alfredo | 16,900 (9%) |
ckn_pesto | 16,702 (9%) |
평균 | 32,653 |
쿼리
SELECT pizza_type_id
, ROUND(SUM(quantity*price), 0) AS sum_supreme
FROM order_pizza
WHERE category = 'Chicken'
GROUP BY pizza_type_id
ORDER BY sum_supreme DESC;
Monetary
피자명 | 백분위 | M값 |
---|---|---|
thai_ckn | 1 | 4 |
bbq_ckn | 0.8 | 4 |
cali_ckn | 0.6 | 3 |
southw_ckn | 0.4 | 2 |
ckn_alfredo | 0.2 | 1 |
ckn_pesto | 0 | 1 |
쿼리
-- 피자별 매출 금액, 매출비중 (error), 주문수, 건당매출
SELECT pizza_type_id
, ROUND(PERCENT_RANK() OVER (ORDER BY sale), 2) AS Monetary_percentage_classic
, CASE WHEN PERCENT_RANK() OVER (ORDER BY sale) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY sale) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY sale) <= 0.75 THEN '3'
ELSE '4' END AS Monetary_quartile_classic
FROM (
SELECT pizza_type_id
, SUM(price * quantity) AS sale
FROM order_pizza
WHERE category = 'Chicken'
GROUP BY pizza_type_id
) AS Monetary
ORDER BY Monetary_percentage_classic DESC;
RFM 점수 = a Recency 점수 + b Frequency 점수 + c * Monetary 점수(단순 비교를 위해 모두 1로 가중치 부여)
상품별 항목 구분 | Recency | Frequancy | Monetary |
---|---|---|---|
메인 상품 | 상 | 상 | 상 |
충성 상품 | 상 | 상 | 하 |
잠재 충성 상품 | 상 | 하 | 상 |
잠재 메인 상품 | 하 | 상 | 상 |
매니악 상품 | 하 | 상 | 하 |
고가 상품 | 하 | 하 | 상 |
개선필요상품 | 하 | 하 | 하 |
pizza_type_id | R | F | M | RFM | 상품 유형 | 특징 |
---|---|---|---|---|---|---|
thai_ckn | 4 | 4 | 4 | 11 | 메인상품 | Chicken 카테고리의 주력 상품 |
bbq_ckn | 4 | 4 | 4 | 11 | 메인상품 | Chicken 카테고리의 주력 상품 |
cali_ckn | 3 | 3 | 3 | 9 | 메인상품 | 준수한 성과를 보이나 특정 부분에서 성과가 떨어질 경우 타입이 변경될 우려가 있음 |
RFM 디벨롭을 통해 메인 상품으로 상향 필요 | ||||||
southw_ckn | 2 | 2 | 2 | 7 | 매니악상품 | 주문 횟수는 자주 발생하나 재주문시간 및 매출비중이 다소 작음 |
ckn_alfredo | 1 | 1 | 1 | 3 | 개선필요상품 | RFM 수치가 낮으나 사이드 식품이므로 세트 상품으로 전략을 노릴 수 있음 |
ckn_pesto | 1 | 1 | 1 | 3 | 개선필요상품 | RFM 수치가 낮으나 사이드 식품이므로 세트 상품으로 전략을 노릴 수 있음 |
메인상품
: thai_ckn, bbq_ckn, cali_ckn
[주력상품이므로 지속적인 매출확보를 위한 액션 필요, 다만 타 카테고리의 메인상품과 비교하여 Frequency 점수가 다소 낮아 주문 빈도 확보가 필요]
매니악상품
: southw_ckn
[주문 횟수는 자주 발생하나 재주문시간 및 매출비중이 다소 작음]
개선필요상품
: ckn_alfredo, ckn_pesto
[ 각 상품의 매출 비중은 작으나 합쳤을 때 매출 비중이 18%정도 차지, 상품군이 6가지밖에 없기 때문에 단종보다는 해당 상품군에 대한 홍보를 통해 성과 제고할 것을 제안]
| category | 피자 종류 | 매출액 ()
(매출액 / 피자종류) | 주문수 (개) | 피자당 주문수 (개)
(주문수 / 피자종류) |
| --- | --- | --- | --- | --- | --- |
| 평균 | 8 | 204,465 | 26,203.5 | 9,355.25 | 1,195.5 |
| Chicken | 6 | 195,920 | 32,653 | 8,536 | 1,423 |
| Classic | 8 | 220,052 | 27,507 | 10,859 | 1,357 |
| Supreme | 9 | 208,196 | 23,133 | 9,085 | 1,009 |
| Veggie | 9 | 193,690 | 21,521 | 8,941 | 993 |
| 합계 | 32 | 817,858 | - | 37,421 | 4,782 |
-- Category로 매출액, 주문수 등
SELECT category
, product
, ROUND(sales, 0) AS sales
, ROUND(sales / product, 0) AS sales_per_product
, cnt_order
, ROUND(cnt_order / product, 0) AS cnt_per_product
FROM (
SELECT category
, ROUND(SUM(quantity*price), 2) AS sales
, ROUND(COUNT(DISTINCT pizza_type_id), 2) AS product
, COUNT(DISTINCT order_id) AS cnt_order
FROM join_data
GROUP BY category
) AS a
ORDER BY product DESC, sales DESC;
상품 별 재주문시간 간격, 상품 별 주문횟수, 상품 별 매출금액을 기준으로 4분위값 부여
아래 기준으로 4분위로 구분하였으며, 단순 비교를 위해 임시로 가중치 모두 1로 설정
Recency
Frequency
Monetary
RFM 점수 분배표
Recency | Frequency | Monetary | 점수분배 |
---|---|---|---|
상위 25% | 상위 25% | 상위 25% | 4 |
상위 50% | 상위 50% | 상위 50% | 3 |
상위 75% | 상위 75% | 상위 75% | 2 |
상위 100% | 상위 100% | 상위 100% | 1 |
피자명 | 재주문시간(분) | 백분율 | R값 |
---|---|---|---|
veggie_veg | 107.4 | 0.88 | 4 |
spinach_fet | 110.3 | 0.75 | 4 |
mexicana | 111.9 | 0.62 | 3 |
five_cheese | 118.1 | 0.5 | 3 |
green_garden | 133.1 | 0.38 | 2 |
mediterraneo | 133.6 | 0.25 | 2 |
ital_veggie | 134.8 | 0.12 | 1 |
spin_pesto | 137.4 | 0 | 1 |
WITH cnt_hour AS (
SELECT pizza_type_id
, TIMEDIFF(time, last_timestamp) AS timediff
FROM (
SELECT pizza_type_id
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM join_data
WHERE category = 'Veggie'
) AS a
SELECT SEC_TO_TIME(SUM(timediff) / COUNT(timediff)) AS avg_reorder_time
FROM cnt_hour
-- 주문 간격 구하기
WITH timediff AS (
SELECT pizza_type_id
, date
, time
, last_timestamp
, TIMEDIFF(time, last_timestamp) AS time_diff -- 직전 주문과의 시간 간격
FROM (
SELECT pizza_type_id
, date
, time
, LAG(time) OVER (PARTITION BY pizza_type_id, date ORDER BY time) AS last_timestamp
FROM join_data
WHERE category = 'Veggie'
ORDER BY pizza_type_id, date, time
) AS last_timestamp
-- 재주문시간 구하기
), reorder_time AS (
SELECT pizza_type_id
, ROUND(AVG(TIME_TO_SEC(DATE_FORMAT(time_diff, '%H:%i:%s')) / 60),1) AS reorder_time
FROM timediff
GROUP BY pizza_type_id
ORDER BY reorder_time ASC
)
-- R값 구하기
SELECT pizza_type_id
, reorder_time
, ROUND(PERCENT_RANK() OVER (ORDER BY reorder_time), 2) AS R_percentage_veggie
, CASE
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.25 THEN '4'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.5 THEN '3'
WHEN PERCENT_RANK() OVER (ORDER BY reorder_time) <= 0.75 THEN '2'
ELSE '1' END AS R_quartile_veggie
FROM reorder_time;
2015년 전체 Veggie 카테고리 피자 상품의 주문수량별 주문건수를 ‘백분율’로 4분위 구분하여 Frequency 분배
Veggie 카테고리 상품별 전체 주문 횟수는 8,941회이며 전체 판매된 상품의 건수는 11,449건으로 주문횟수는 적으나 판매된 건수는 Supreme 카테고리, Chicken 카테고리보다도 많았음. ( 카테고리별 상품 판매 갯수 Supreme : 11,777건 & Chicken : 10,815건 )
Veggie 카테고리의 상품 별 전체 주문 수 비교시 four_cheese(1,850건)으로 가장 높으며 일별 주문건수 또한 5건으로 평균 3.48회를 웃도는 수치를 기록 본 상품의 경우 R, M 값도 우수하기 때문에 성과가 저조한 피자와 set 조합으로 성과 상향을 제안
그 외에도 veggie_veg (1,510건) > mexicana(1,456건) > spinach_fet(1,432건) > five_cheese(1,359건) 순으로 주문수가 높았으며 평균 일별 주문건수 보다 높은 수치를 보임
다만 하위 성과를 기록하고 있는 상품인 mediterraneo(923건) < spin_pesto(957건) <ital_veggie(975건) < green_garden(987건) 의 우 주문건수 1,000건을 밑도는 수치 기록, 해당 상품군의 경우 일 평균 구매 빈도 또한 3회 미만을 보이며 평균보다 낮은 주문수를 보임
Veggie 카테고리의 경우 주문횟수는 가장 낮으나 판매 건수는 높아 충성도가 있는 카테고리라고 판단, 다만 매출액이 가장 낮은 군이므로 매출액 상향을 위하여 성과가 낮은 상품 중 특히 저조한 상품을 단종하여 다른 피자 상품에 집중할 것을 제안드릴 예정
Veggie 상품별 주문건수 및 Frequency 점수 분배
| 피자명 | 주문수(건) | 일별 주문건수
(상품 주문건수 / 365) | 백분율 | F값 |
| --- | --- | --- | --- | --- |
| 합계 | 11,449 | - | - | - |
| four_cheese | 1,850 | 5.07 | 1 | 4 |
| veggie_veg | 1,510 | 4.14 | 0.88 | 4 |
| mexicana | 1,456 | 3.99 | 0.75 | 3 |
| spinach_fet | 1,432 | 3.92 | 0.62 | 3 |
| five_cheese | 1,359 | 3.72 | 0.5 | 2 |
| green_garden | 987 | 2.70 | 0.38 | 2 |
| ital_veggie | 975 | 2.67 | 0.25 | 1 |
| spin_pesto | 957 | 2.62 | 0.12 | 1 |
| mediterraneo | 923 | 2.53 | 0 | 1 |
| 평균 | 1,272 | 3.48 | - | - |
쿼리
SELECT pizza_type_id
, cnt
, ROUND((cnt/ 365), 2) avg_day
, ROUND(PERCENT_RANK() OVER (ORDER BY cnt), 2) AS F_percentage_Veggie
, CASE WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY cnt) <= 0.75 THEN '3'
ELSE '4' END AS F_quartile_Veggie
FROM (
SELECT pizza_type_id
, COUNT(DISTINCT order_details_id) AS cnt
FROM join_data
WHERE category = 'veggie'
GROUP BY pizza_type_id ) AS cnt_Veggie
ORDER BY cnt DESC;
Veggie 부분 Monetary의 경우 카테고리 각 상품의 매출액(price*quantity)의 평균을 4분위로 분배하여 점수 부여
해당 카테고리는 9가지의 상품군으로 가장 많은 상품들을 제공하고 있으나 2015년 매출액은 총 $195,690으로 전체 카테고리 중 매출 비중이 가장 낮음
Veggie 카테고리 중 four_cheese가 $32,266 기록하여 매출비중 17% 차지해 가장 큰 매출비중을 보였으며 그 뒤로 mexicana, five_cheese, veggie_veg, spinach_fet 순으로 매출을 기록하고 있음
매출 비중이 컸던 four_cheese 상품의 경우 전체 상품군 중 매출 9위를 차지, Veggie 카테고리 평균 매출액을 훨씬 상회하며 주문건수 및 재주문시간 또한 우수한 성과를 보임 이에 재주문건수 및 주문건수가 저조한 상품과 조합하여 하위상품의 성과를 올릴 것을 제안
하위 매출액을 기록한 ital_veggie, spin_pesto, mediterraneo, green_garden 상품들의 경우 Veggie 카테고리 매출액 한 자릿수의 매출비중을을 보임.
특히 매출이 가장 작은 green_garden 상품의 경우 매출비중도 가장 작으며 Recency, Frequency 부분에서도 저조한 성과를 보임
그 외 하위매출을 기록하고 있는 ital_veggie, spin_pesto, mediterraneo 상품의 경우 마찬가지로 한자리 수의 매출을 보이곤 있으나 성과가 준수한 상품과의 조합으로 혹은 이벤트 메뉴로 구성하 성과 개선을 기대할 것을 제안드림
Veggie 피자별 상품별 매출액
피자명 | 매출액($) / 매출비중(%) |
---|---|
합계 | 193,690 (100%) |
four_cheese | 32,266 (17%) |
mexicana | 26,781 (14%) |
five_cheese | 26,066 (13%) |
veggie_veg | 24,375 (13%) |
spinach_fet | 23,271 (12%) |
ital_veggie | 16,019 (8%) |
spin_pesto | 15,596 (8%) |
mediterraneo | 15,360 (8%) |
green_garden | 13,956 (7%) |
평균 | 21,521 |
쿼리
SELECT pizza_type_id
, ROUND(SUM(quantity*price), 0) AS sum_veggie
FROM join_data
WHERE category = 'Veggie'
GROUP BY pizza_type_id
ORDER BY sum_veggie DESC;
Monetary
(Veggie 카테고리 상품의 매출액(price*quantity) 평균(일평균) + 4분위)
피자명 | 매출액($) | 백분율 | M값 |
---|---|---|---|
four_cheese | 32,266 | 1 | 4 |
mexicana | 26,781 | 0.88 | 4 |
five_cheese | 26,066 | 0.75 | 3 |
veggie_veg | 24,375 | 0.62 | 3 |
spinach_fet | 23,271 | 0.5 | 2 |
ital_veggie | 16,019 | 0.38 | 2 |
spin_pesto | 15,596 | 0.25 | 1 |
mediterraneo | 15,360 | 0.12 | 1 |
green_garden | 13,956 | 0 | 1 |
쿼리
-- 피자별 매출액, 일평균 매출액
SELECT pizza_type_id
, sum_sale
, avg_sale
, ROUND(PERCENT_RANK() OVER (ORDER BY avg_sale), 2) AS Monetary_percentage_veggie
, CASE WHEN PERCENT_RANK() OVER (ORDER BY avg_sale) <= 0.25 THEN '1'
WHEN PERCENT_RANK() OVER (ORDER BY avg_sale) <= 0.5 THEN '2'
WHEN PERCENT_RANK() OVER (ORDER BY avg_sale) <= 0.75 THEN '3'
ELSE '4' END AS Monetary_quartile_veggie
FROM (
SELECT pizza_type_id
, ROUND(SUM(price * quantity), 0) AS sum_sale
, ROUND(SUM(price * quantity)/ 365, 0) AS avg_sale
FROM join_data
WHERE category = 'Veggie'
GROUP BY pizza_type_id
) AS Monetary
ORDER BY Monetary_percentage_veggie DESC;
RFM 점수 = a Recency 점수 + b Frequency 점수 + c * Monetary 점수(단순 비교를 위해 모두 1로 가중치 부여)
상품별 항목 구분 | Recency | Frequancy | Monetary |
---|---|---|---|
메인 상품 | 상 | 상 | 상 |
충성 상품 | 상 | 상 | 하 |
잠재 충성 상품 | 상 | 하 | 상 |
잠재 메인 상품 | 하 | 상 | 상 |
매니악 상품 | 하 | 상 | 하 |
고가 상품 | 하 | 하 | 상 |
개선필요상품 | 하 | 하 | 하 |
피자명 | R | F | M | RFM | 상품유형 | 특징 |
---|---|---|---|---|---|---|
four_cheese | 4 | 4 | 4 | 12 | 메인상품 | 재주문시간, 주문 횟수, 매출액이 우수한 주력 상품. 지속적으로 성과 유지 필요 |
veggie_veg | 4 | 4 | 3 | 11 | 메인상품 | 재주문시간, 주문 횟수, 매출액이 우수한 주력 상품. 지속적으로 성과 유지 필요 |
mexicana | 3 | 3 | 4 | 11 | 메인상품 | 재주문시간, 주문 횟수, 매출액이 우수한 주력 상품. 지속적으로 성과 유지 필요 |
spinach_fet | 4 | 3 | 2 | 10 | 충성상품 | 매출량은 다소 떨어지나 재주문시간 및 주문건수가 우수, 충성도가 높아 up-selling 필요 |
five_cheese | 3 | 2 | 3 | 9 | 잠재메인상품 | RFM 이 준수한 성과를 보임, 지속적으로 관리 시 잠재적으로 메인 상품으로 상향 가능 |
green_garden | 2 | 2 | 1 | 5 | 개선필요상품 | 매출 저조, 다만 제품의 특성상 비건 및 베지터리안 타겟 공략 제안 |
+ 메인 상품과의 세트 조합을 통해 고객들에게 시식을 할 수 있도록 운영해볼 것을 제안 | ||||||
mediterraneo | 2 | 1 | 1 | 5 | 개선필요상품 | 매출 저조, 지중해식 상품으로 휴가시즌 단기간 운영하여 프로모션으로 활용해 볼 것을 제안 |
+ 메인 상품과의 세트 조합을 통해 고객들에게 시식을 할 수 있도록 운영해볼 것을 제안 | ||||||
ital_veggie | 1 | 1 | 2 | 5 | 개선필요상품 | 재주문시간 저조. 이탈리아식 상품으로 휴가시즌, 단기간 운영하여 프로모션으로 활용 제안 |
+ 메인 상품과의 세트 조합을 통해 고객들에게 시식을 할 수 있도록 운영해볼 것을 제안 | ||||||
spin_pesto | 1 | 1 | 1 | 4 | 단종제안 | Veggie 상품들 중 가장 낮은 RFM 수치 기록, 해당 상품 단종하여 타 상품에 매출 집중권장 |
메인상품
: four_cheese, veggie_veg, mexicana
[RFM 점수가 *모두 4점대인 상품 : four_cheese]*
[RFM 점수가 한 개 이상 부분에서만 4점대인 경우 : veggie_veg, mexicana]
충성상품
: spinach_fet
[ 재주문시간 및 주문횟수의 성과는 우수하나 매출량이 다소 작은 상품. 충성도는 높기 때문에 다른 상품의 조합 또는 옵션을 추가하여 up-selling 전략이 필요]
잠재메인상품
: five_cheese
[ RFM 성과를 보이나, 한 부분에서의 성과 저조시 타입 변경 우려가 있으며 단독 상품으로 타 카테고리와의 RFM 성과 비교시 다소 저조하여 잠재 메인상품으로 분류 **]**
개선필요상품
: green_garden, mediterraneo, ital_veggie
[ 각 상품의 매출 비중은 작으나 합쳤을 때 매출 비중이 18%정도 차지, 상품군이 6가지밖에 없기 때문에 단종보다는 해당 상품군에 대한 홍보를 통해 성과 제고할 것을 제안]
단종제안
: spin_pesto
[ Veggie 카테고리 중 가장 낮은 성과를 차지, 매출 또한 저조하여 해당상품 단종 후 가짓수를 줄여 타 상품에 집중할 것을 권장 ]
프로젝트 내용을 보고서로 작성했다면, 처음부터 끝까지 쭉 읽어보면서 체크리스트를 확인해보세요. 놓친 부분은 없는지, 더 보완할 부분은 없는지 찾아보면서 보고서의 완성도를 높여보세요!
그래프를 그렸다면 아래 항목들이 모두 포함되어 있는지 확인해주세요.
표를 넣어줬다면 아래 항목들이 모두 포함되어 있는지 확인해주세요.