관리 메뉴

ilovechoonsik

[STARTERS 4기 TIL] SQL 심화 #5 - Z-차트 및 그룹핑 함수 (230414) 본문

STARTERS 4기 🚉/TIL 👶🏻

[STARTERS 4기 TIL] SQL 심화 #5 - Z-차트 및 그룹핑 함수 (230414)

춘시기좋아 2023. 4. 14. 12:43

 

 

📖 오늘 내가 배운 것

 

1. Z차트

2. 그룹핑 함수 - group by / grouping sets / roll up / cube

3. 과제

 

 


1. Z 차트

- 월별 매출

- 매출누계 : 해당 월 매출에 이전 월까지 매출 누계 (단기적인 추이를 확인할 수 있다)

- 이동년계 : 해당 월의 매출에 과거 11개월의 매출을 합한 값 (최근 1년치 누적 합계) - 장기적인, 그래프에 표현되지 않은 11개월 매출의 추이를 확인할 수 있다.

출처 : https://blog.naver.com/socialmedia/220194062598

A : 안정적, 정체기, 추가성장 위한 액션 필요

B : 매출 증가 추세

C : 매출 감소 추세, 단기 장기 모두 감소세, 성장전환을 위한 액션 필요

-> 상승/하락에 대한 원인을 분석하기 위해 다른 지표 이용한 분석이 필요하다!

 

📌 그려보자

필요한 컬럼?

year / month / 월별 매출 / 매출 누계 / 이동연계 (10개월 전~현재월 매출 (11개월))

 

우리 데이터로 정상적인 결과를 뽑을 수 있으려면

97년 6월 ~ 98년 4월로 기간 제한을 두어야 한다

/*Z-차트*/
with cte_products_sales as (
select -- order
	   o.order_id as 주문번호
	 , o.customer_id as 고객번호
	 , o.order_date as 주문일
	 , to_char(order_date, 'YYYY') as 연
	 , to_char(order_date, 'MM')  as 월
	 , to_char(order_date, 'dd') as 일
	 , to_char(order_date, 'YYYY-MM') as 연일
	 -- order_details
	 , od.product_id as 제품ID
	 , od.unit_price as 판매당시금액
 	 , od.quantity as 수량
 	 , od.discount as 할인율
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as 매출액
	 -- categories
	 , c.category_id as 카테고리ID
	 , c.category_name as 카테고리명
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name as 제품명
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
), cte_amount as (
-- 1. 제품별 연-월에 따른 월별 매출
select 연
	 , 월
	 , sum(매출액) as 월별매출
from cte_products_sales
group by 1,2
order by 1,2
), cte_base_amount as (
select *
	 , case 
		 when 연||월 between '199706' and '199804' then 월별매출
	 	 else 0
	 	end as 기준월매출
	 from cte_amount
	 order by 1,2
), calc as (
-- 2. 매출누계
select *
	 , sum(기준월매출) over (order by 연, 월) 누적합계
	 , sum(월별매출) over (order by 연, 월 rows between 10 preceding and current row) as 이동연계
from cte_base_amount
limit 11 offset 11
-- 나는 limit으로 했는뎅 where 기준월매출 != 0 도 쓸 수 있다!
)
select 연, 월, 월별매출, 누적합계, 이동연계
from calc;

++++

한 가지 방법이 더 존재

/*Z-차트222222*/
with cte_products_sales as (
select -- order
	   o.order_id as 주문번호
	 , o.customer_id as 고객번호
	 , o.order_date as 주문일
	 , to_char(order_date, 'YYYY') as 연
	 , to_char(order_date, 'MM')  as 월
	 , to_char(order_date, 'dd') as 일
	 , to_char(order_date, 'YYYY-MM') as 연월
	 -- order_details
	 , od.product_id as 제품ID
	 , od.unit_price as 판매당시금액
 	 , od.quantity as 수량
 	 , od.discount as 할인율
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as 매출액
	 -- categories
	 , c.category_id as 카테고리ID
	 , c.category_name as 카테고리명
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name as 제품명
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
), cte_monthly_amount as (
-- 1. 월별 매출 구하기
select 연, 월, 연월, sum(매출액) as 월별매출 
from cte_products_sales
group by 1,2,3
order by 1,2,3
), cte_amount_moving as (
-- 2. 이동연계 구하기
select *
	 , sum(월별매출) over(rows between 10 preceding and current row) as 이동연계
from cte_monthly_amount
), cte_amount_sum as (
-- 3. 매출누계 구하기
select *
	 , sum(월별매출) over(order by 연월) as 매출누계
from cte_amount_moving
where 연월 between '1997-06' and '1998-04'
)
select 연, 월, 월별매출, 이동연계, 매출누계
from cte_amount_sum

 

1, 2 방법은

이동연계를 구하기 위해서는 테이블에 1997-06 이전 12개월의 월별매출이 필요하고

매출누계를 구하기 위해서는 현재 테이블의 기간이 1997-06 ~ 1998-04 여야 한다는 점을 어떻게 타개할 것이냐에 따라 갈린다

 

1번 방법은 : 매출누계를 구하기 위한 새로운 컬럼을 case when을 통해 만들어 주었다! 1997-06 ~ 1998-04 기간에 해당하는 행에 대해서만 월별 매출을 뽑고 나머지 행은 0을 줌으로써 다른 조건이 어떻든 이 컬럼에 대한 매출누계 계산은 일정할 수밖에 없게 만들었다.

 

2번 방법은 : 이동연계를 먼저 구해 CTE 테이블에 고정시킨 후 매출누계를 WHERE절과 함께 구하였다.

처음에 쿼리의 실행 순서가 FROM WHERE- ~ - SELECT 일 텐데 어떻게 WHERE 절에 조건을 걸었을 때 이동연계의 값을 그대로 유지하는 것이 가능한 것인지 의문이 들었는데, 이미 이전 CTE 테이블에서 계산되어 고정된 이동연계 값의 결과를 가져오기 때문에 바뀐 조건에 의해 값이 변하지 않는다는 당연한 사실을 인지하게 되었다

 

📌 카테고리 별로 그려보자

/*Z-차트*/
-- 태블로용 카테고리 별 z-차트
with cte_products_sales as (
select -- order
	   o.order_id as 주문번호
	 , o.customer_id as 고객번호
	 , o.order_date as 주문일
	 , to_char(order_date, 'YYYY') as 연
	 , to_char(order_date, 'MM')  as 월
	 , to_char(order_date, 'dd') as 일
	 , to_char(order_date, 'YYYY-MM') as 연일
	 -- order_details
	 , od.product_id as 제품ID
	 , od.unit_price as 판매당시금액
 	 , od.quantity as 수량
 	 , od.discount as 할인율
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as 매출액
	 -- categories
	 , c.category_id as 카테고리ID
	 , c.category_name as 카테고리명
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name as 제품명
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
), cte_amount as (
-- 1. 제품별 연-월에 따른 월별 매출
select 카테고리명
	 , 연
	 , 월
	 , sum(매출액) as 월별매출
from cte_products_sales
group by 1,2,3
order by 1,2,3
), cte_base_amount as (
select *
	 , case 
		 when 연||월 between '199706' and '199804' then 월별매출
	 	 else 0
	 	end as 기준월매출
	 from cte_amount
	 order by 1,2,3
), calc as (
-- 2. 매출누계
select *
	 , sum(기준월매출) over (partition by 카테고리명 order by 연, 월) 누적합계
	 , sum(월별매출) over (partition by 카테고리명 order by 연, 월 rows between 10 preceding and current row) as 이동연계
from cte_base_amount
)
select 카테고리명, 연, 월, 월별매출, 누적합계, 이동연계
from calc
where 연||월 between '199706' and '199804';

 

2. 그룹핑 함수 - group by / grouping sets / roll up

추후에 특정 데이터를 받아와야 할 일이 많다면? 단순노동 및 반복을 최소화할 수 있다!

3.1 grouping sets

📌 카테고리별 매출액 분석

--------------------------------------------------------------------------------------------------
-- 카테고리별 매출액
-- 그룹함수 - grouping sets
---- 차후에 타인이 ~~한 데이터 보여줄 수 있어? 했을 때, 단순노동 및 반복을 최소화할 수 있다.

with cte_products_sales as (
select -- order
	   o.order_id as 주문번호
	 , o.customer_id as 고객번호
	 , o.order_date as 주문일
	 , to_char(order_date, 'YYYY') as 연
	 , to_char(order_date, 'MM') as 월
	 , to_char(order_date, 'dd') as 일
	 , to_char(order_date, 'q') as 분기
	 -- order_details
	 , od.product_id as 제품ID
	 , od.unit_price as 판매당시금액
 	 , od.quantity as 수량
 	 , od.discount as 할인율
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as 매출액
	 -- categories
	 , c.category_id as 카테고리ID
	 , c.category_name as 카테고리명
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name as 제품명
 	 , p.unit_price as 마스터단가
 	 , p.discontinued as 단종여부
 	 -- 서플라이어
 	 , s.supplier_id as 공급자ID
 	 , s.contact_name as 공급사
 	 , s.country as 공급사국가
	 , s.city as 공급사도시
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
	 left join suppliers s ON p.supplier_id = s.supplier_id
)
-- 제품 속성 별 매출액 (grouping sets)
, cte_grouping_sets as (
select 카테고리명, 제품명, 공급사, 공급사국가, 공급사도시, sum(매출액) as 매출액
from cte_products_sales
group by grouping sets (카테고리명, 제품명, 공급사, 공급사국가, (공급사국가,공급사도시),())
--그룹 안에서 묶어서 보고 싶은 애들이 있다면? ()로 묶어서 한 개의 인자로 던지기
-- 전체 집계를 보고 싶다면? 그냥 빈 괄호 넣어주기 ()!
)
-- 여기에 그룹화, window function 사용하기 위해
-- 카테고리별 매출액
, cte_category_amount as (
select 카테고리명, 매출액
from cte_grouping_sets
where 카테고리명 is not null
)
-- 제품별 매출액 
, cte_product_amount as (
select 제품명, 매출액
from cte_grouping_sets
where 제품명 is not null
)
-- 공급사별 매출액
, cte_company_amount as (
select 공급사, 매출액
from cte_grouping_sets
where 공급사 is not null
)
-- 공급국가별 매출액
, cte_country_amount as (
select 공급사국가, 매출액
from cte_grouping_sets
where 공급사국가 is not null and 공급사도시 is null -- 공급국가-도시가 묶여있기 때문에 null 처리 잘 해줘야 한다.
)
-- (공급국가,공급도시)별 매출액
, cte_city_amount as (
select 공급사도시, 매출액
from cte_grouping_sets
where 공급사국가 is not null and 공급사도시 is not null -- 공급국가-도시가 묶여있기 때문에 null 처리 잘 해줘야 한다.
)
-- 전체 매출액
, cte_total_amount as (
select max(매출액)
from cte_grouping_sets
)
-- 전체 매출액 2
, cte_to_amount as(
select 'all' as 전체, 매출액
from cte_grouping_sets
order by 매출액 desc
limit 1
)
-- 카테고리별 매출액 : cte_grouping_sets, 한번 만들어 놓으면 이후에 select로 편하게 구해올 수 있다!
-- 제품별 매출액 : cte_product_amount
-- 공급사별 매출액 : cte_company_amount
-- 공급사국가별 매출액 : cte_country_amount
-- (공급국가,공급도시)별 매출액 : cte_city_amount
-- 전체 매출액 : cte_total_amount
-- 전체 매출액 2 : cte_to_amount
select *
from cte_to_amount
order by 1;

 

📌 연도, 분기, 월, 일별 매출액, 주문건수 집계

연도-분기-월-일을 괄호로 묶게 되면 나중에 null 처리하기 너무 귀찮으니 가공을 하는 게 좋다!

- year

- year-q

- year-m

- year-mm-dd

- all

 

--------------------------------------------------------------------------------------------------
-- 연도, 분기, 월, 일별 매출액
-- 그룹함수 - grouping sets
---- 차후에 타인이 ~~한 데이터 보여줄 수 있어? 했을 때, 단순노동 및 반복을 최소화할 수 있다.

with cte_products_sales as (
select -- order
	   o.order_id as 주문번호
	 , o.customer_id as 고객번호
	 , o.order_date as 주문일
	 , to_char(order_date, 'YYYY') as 연
	 , to_char(order_date, 'MM') as 월
	 , to_char(order_date, 'dd') as 일
	 , to_char(order_date, 'q') as 분기
	 -- order_details
	 , od.product_id as 제품ID
	 , od.unit_price as 판매당시금액
 	 , od.quantity as 수량
 	 , od.discount as 할인율
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as 매출액
	 -- categories
	 , c.category_id as 카테고리ID
	 , c.category_name as 카테고리명
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name as 제품명
 	 , p.unit_price as 마스터단가
 	 , p.discontinued as 단종여부
 	 -- 서플라이어
 	 , s.supplier_id as 공급자ID
 	 , s.contact_name as 공급사
 	 , s.country as 공급사국가
	 , s.city as 공급사도시
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
	 left join suppliers s ON p.supplier_id = s.supplier_id
), cte_grouping_set_date as (
select 연 as year
	 , 연||'-'||분기 as quarter
	 , 연||'-'||월 as month
	 , 연||'-'||월||'-'||일 as day
	 , sum(매출액) as 매출액
from cte_products_sales
group by grouping sets (1,2,3,4,())
order by 1,2,3,4
)
-- year별 매출액
, cte_year_amount as (
select year, 매출액
from cte_grouping_set_date
where year is not null
)
-- quater별 매출액
, cte_quater_amount as (
select quarter, 매출액
from cte_grouping_set_date
where quarter is not null
)
-- month별 매출액 
, cte_month_amount as (
select month, 매출액
from cte_grouping_set_date
where month is not null
)
-- day별 매출액
, cte_day_amount as (
select day, 매출액
from cte_grouping_set_date
where day is not null
)
-- total 매출액
, cte_total_amount as (
select max(매출액)
from cte_grouping_set_date
)
-- year별 매출액 : cte_year_amount
-- quater별 매출액 : cte_quater_amount
-- month별 매출액 : cte_month_amount
-- day별 매출액 : cte_day_amount
-- 매출액 total : cte_total_amount
select *
from cte_quater_amount

시계열 가공을 제외한 나머지 부분은 위 카테고리-제품 매출 때와 방식은 동일하다!

 

3.2 rollup 함수

소계 내주는 함수!

 

순서 주의~

가장 큰 분류가 앞으로 오게 인자 줘야 함

group by rollup (대, 중, 소)

with cte_products_sales as (
select -- order
	   o.order_id as 주문번호
	 , o.customer_id as 고객번호
	 , o.order_date as 주문일
	 , to_char(order_date, 'YYYY') as 연
	 , to_char(order_date, 'MM') as 월
	 , to_char(order_date, 'dd') as 일
	 , to_char(order_date, 'q') as 분기
	 -- order_details
	 , od.product_id as 제품ID
	 , od.unit_price as 판매당시금액
 	 , od.quantity as 수량
 	 , od.discount as 할인율
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as 매출액
	 -- categories
	 , c.category_id as 카테고리ID
	 , c.category_name as 카테고리명
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name as 제품명
 	 , p.unit_price as 마스터단가
 	 , p.discontinued as 단종여부
 	 -- 서플라이어
 	 , s.supplier_id as 공급자ID
 	 , s.contact_name as 공급사
 	 , s.country as 공급사국가
	 , s.city as 공급사도시
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
	 left join suppliers s ON p.supplier_id = s.supplier_id
), cte_category_product_rollup as (
select 카테고리명
	 , coalesce(제품명,'소계') as 제품명
	 , sum(매출액)
from cte_products_sales
group by rollup (카테고리명, 제품명)
order by 1,2
)
select 연 as year
	 , 분기 as quarter
	 , 월 as month
	 , sum(매출액) as 매출액
from cte_products_sales
group by rollup(1,2,3)
order by 1,2,3

 

 

3.3 cube 함수

모든 경우의 수로 그룹핑해서 뿌리고 각각 집계한다

with cte_products_sales as (
select -- order
	   o.order_id as 주문번호
	 , o.customer_id as 고객번호
	 , o.order_date as 주문일
	 , to_char(order_date, 'YYYY') as 연
	 , to_char(order_date, 'MM') as 월
	 , to_char(order_date, 'dd') as 일
	 , to_char(order_date, 'q') as 분기
	 -- order_details
	 , od.product_id as 제품ID
	 , od.unit_price as 판매당시금액
 	 , od.quantity as 수량
 	 , od.discount as 할인율
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as 매출액
	 -- categories
	 , c.category_id as 카테고리ID
	 , c.category_name as 카테고리명
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name as 제품명
 	 , p.unit_price as 마스터단가
 	 , p.discontinued as 단종여부
 	 -- 서플라이어
 	 , s.supplier_id as 공급자ID
 	 , s.contact_name as 공급사
 	 , s.country as 공급사국가
	 , s.city as 공급사도시
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
	 left join suppliers s ON p.supplier_id = s.supplier_id
), cte_category_product_rollup as (
select 카테고리명
	 , coalesce(제품명,'소계') as 제품명
	 , sum(매출액)
from cte_products_sales
group by rollup (카테고리명, 제품명)
order by 1,2
)
select 연 as year
	 , 분기 as quarter
	 , 월 as month
	 , sum(매출액) as 매출액
from cte_products_sales
group by cube (1,2,3)
order by 1,2,3

연도-분기에 종속되는 월

독립적으로 계산된 월

등등 모든 조합 가지고 집계 

 

3. 과제는?

고객을 분석하기 위한 테이블 만들기,

만들고 고객의 속성 별 이라던가 고객의 주문 기간이라던가 속한 지역이라던가 국가별이라던가

우리가 선정해서

위 그룹 함수 적용을 어떻게 할 것인가? 알아서 생각해 보기!

GROUPING SETS, ROLL UP, CUBE

 

주제 : 고객 속성, 구매 이력에 대한 집계

조건 :  그룹함수 이용

지표 : 자유

방안 : 오늘 했던 것처럼 복-붙 했을 때 바로 확인할 수 있도록 만들기

 

--------------------------------------------------------------------------------------------------
-- 230414 신사율 개인과제
-- grouping sets
---- 단순노동 및 반복을 최소화할 수 있다

with cte_main_table as (
select -- order
	   o.order_id
	 , o.customer_id
	 , o.order_date
	 , o.ship_country as scountry
	 , to_char(order_date, 'YYYY') as year
	 , to_char(order_date, 'MM') as month
	 , to_char(order_date, 'dd') as day
	 , to_char(order_date, 'q') as quarter
	 -- order_details
	 , od.product_id 
	 , od.unit_price 
 	 , od.quantity 
 	 , od.discount 
	 , round( od.unit_price * od.quantity * (1-od.discount) ) as amount
	 -- categories
	 , c.category_id
	 , c.category_name
	 --, p.product_id as 제품ID order_details와 중복!
 	 , p.product_name
 	 , p.unit_price -- 마스터단가
 	 , p.discontinued -- 단종여부
 	 -- supplier
 	 , s.supplier_id -- 공급사ID
 	 , s.contact_name -- 공급사
	 -- customers
	 , c2.customer_id
	 , c2.company_name
	 , c2.country
	 , c2.city
from orders o
	 left join order_details od ON od.order_id = o.order_id
	 left join products p on p.product_id = od.product_id
	 left join categories c on p.category_id = c.category_id
	 left join suppliers s ON p.supplier_id = s.supplier_id
	 left join customers c2 ON o.customer_id = c2.customer_id
)
------------------------------ 날짜 -------------------------------
-- 연/분기/월/일 grouping_set 테이블
, cte_grouping_set_customer_date as (
select company_name
	 , year
	 , year||'-'||quarter as quarter
	 , year||'-'||month as month
	 , year||'-'||month||'-'||day as day
	 , sum(amount) as total_amount
from cte_main_table
group by grouping sets ((1,2),(1,3),(1,4),(1,5),())
order by 1,2,3,4
)
-- 고객 별 year별 매출액
, cte_customer_year_amount as (
select company_name, year, total_amount
from cte_grouping_set_customer_date
where year is not null
order by 1,2
)
-- 고객 별 quater별 매출액
, cte_customer_quater_amount as (
select company_name, quarter, total_amount
from cte_grouping_set_customer_date
where quarter is not null
order by 1,2
)
-- 고객 별 month별 매출액 
, cte_customer_month_amount as (
select company_name, month, total_amount
from cte_grouping_set_customer_date
where month is not null
order by 1,2
)
-- 고객 별 day별 매출액
, cte_customer_day_amount as (
select company_name, day, total_amount
from cte_grouping_set_customer_date
where day is not null
order by 1,2
)
-- 고객 별 total 매출액
, cte_customer_total_amount as (
select max(total_amount)
from cte_grouping_set_customer_date
)
-- 각 연도 별 고객 매출 순위
, cte_customer_year_amount_rank as(
select year
	 , company_name
	 , total_amount
	 , rank() over(partition by year order by total_amount DESC)
from cte_grouping_set_customer_date
where year is not null
)
-- 각 분기 별 고객 매출 순위
, cte_customer_quarter_amount_rank as (
select quarter
	 , company_name
	 , total_amount
	 , rank() over(partition by quarter order by total_amount DESC)
from cte_grouping_set_customer_date
where quarter is not null
)
------------------------------ 고객 매출 순위 -------------------------------
-- 고객 별 총 매출액
, cte_customer_amount as (
select company_name
	 , sum(amount) as total_amount
	 , rank () over(order by sum(amount)) as rank
from cte_main_table
group by 1
order by 3 DESC
)
-- 고객 별 총매출에서 차지하는 비율
, cte_customer_amount_percentage as (
select *
	 , total_amount / sum(total_amount) over() * 100::integer||'%' as "amount%"
from cte_customer_amount
order by 3 desc
)
------------------------------ 지역 -------------------------------
-- 고객사/지역/도시 grouping_set 테이블
, cte_grouping_set_customer_country_city as (
select country
	 , city
	 , company_name
	 , sum(amount) as amount
from cte_main_table
group by grouping sets (1,(1,2),2,(2,3),3,())
order by 1,2,3,4
)
-- 지역-도시 별 고객 분포
, cte_customer_country_city_distribution as (
select country
	 , city
	 , count(distinct company_name)
from cte_main_table
group by rollup (1,2)
order by 1
)
-- 지역 별 고객 총 매출액
, cte_country_customer_amount as (
select country, company_name, sum(amount) as amount
from cte_main_table
group by rollup(1,2)
order by 1,2
)
-- 지역 별 고객 매출 및 지역에서 차지하는 비율
, cte_country_customer_amount_percentage as (
select *
	 , round(amount * 2 * 100 / case when company_name is null then null
	 	else (sum(amount) over(partition by country)) end)||'%' as percentage
from cte_country_customer_amount
order by 1,4
)
-- 각 도시에 속하는 고객 별 매출액 순위
, cte_city_customer_rank as (
select city, company_name, amount
	 , rank() over (order by amount) as rank
from cte_grouping_set_customer_country_city
where city is not null and company_name is not null
order by 4 DESC
)
------------------------------ 카테고리 --------------------------------
-- 고객별 카테고리, 제품 매출액
, cte_category_product_rollup as (
select company_name
	 , category_name
	 , product_name
	 , sum(amount)
from cte_main_table
group by rollup (company_name, category_name, product_name)
order by 1,2,3
)
-- 고객별 3회 이상 주문한 제품과 주문액
, cte_customer_order_cnt_amount as (
select company_name, product_name, count(product_name) as order_cnt, sum(amount) as amount
from cte_main_table
group by 1,2
having count(product_name) >= 3
order by 1,2
)
------------------------------ 날짜 -------------------------------
-- 고객사별 year별 매출액 : cte_customer_year_amount
-- 고객사별 quater별 매출액 : cte_customer_quater_amount
-- 고객사별 month별 매출액 : cte_customer_month_amount
-- 고객사별 day별 매출액 : cte_customer_day_amount
-- 전체 매출액 total : cte_customer_total_amount
-- 각 연도 별 고객 매출 순위 : cte_customer_year_amount_rank
-- 각 분기 별 고객 매출 순위 : cte_customer_quarter_amount_rank
------------------------------ 고객-매출 순위 및 비율 -------------------------------
-- 고객 별 총 매출액 및 순위 : cte_customer_amount
-- 고객 별 총매출에서 차지하는 비율 : cte_customer_amount_percentage
------------------------------ 지역 -------------------------------
-- 지역-도시 별 고객 분포 : cte_customer_country_city_distribution
-- 지역 별 고객 총 매출 : cte_country_customer_amount
-- 지역 별 고객 매출 및 지역에서 차지하는 비율 : cte_country_customer_amount_percentage
-- 각 도시에 속하는 고객 별 매출액 : cte_city_customer_rank
------------------------------ 카테고리 -------------------------------
-- 고객별 카테고리, 제품 매출액 : cte_category_product_rollup
-- 고객별 3회 이상 주문한 제품과 주문액 : cte_customer_order_cnt_amount
select *
from cte_customer_order_cnt_amount

💪🏻 좋았던 점, 앞으로 개선해야 할 점 (추가로 배워야 할 점)

 

📌 grouping sets, rollup, cube 등의 그룹핑 함수들을 학습했다.

헌데 이러한 함수들이 분석 시 얼마나 효율적 일지 아직 와닿지 않으며, 실무에서 얼마큼 활용될지 궁금하다

더 학습해봐야 할 거 같다!

 

 

#유데미, #유데미코리아, #유데미부트캠프, #취업부트캠프, #부트캠프후기, #스타터스부트캠프, #데이터시각화 #데이터분석 #태블로

Comments