홍동이의 성장일기
[👩💻TIL 49일차 ] 유데미 스타터스 취업 부트캠프 4기 본문
📍 Z차트
➡️ 시간의 흐름에 따라 매출의 변화 확인하기
- 월별매출: 1자이면 월별매출이 다 똑같은 것
- 매출누계: 해당 월 매출에 이전 월까지 매출 누계를 합한 값
- 이동합계(년): 해당 월의 매출에 과거 11개월의 매출을 합한 값 (최근 1년치 누적 합계 = 12개월)
- 그래프에 표시되지 않은 과거 1년동안의 매출 추이도 읽을 수 있음
- A: 추가성장을 위한 액션 필요
- C: 단기, 장기 모두 감소세 / 성장전환을 위한 액션 필요
➡️ 추세파악을 했다면, 추세에 대한 원인을 파악하기 위해 추가 분석 필요
실습
📍 1997-06 ~ 1998-04 11개월의 Z차트 그리기
➡️ 위와 같은 테이블을 만들어보자.
[✔️ 강사님 코드]
-- 1.월매출
, cte_amount as(
select year, month, round(sum(amount)) as 월매출
from cte_products_sale
-- where category_id=1
group by 1,2
order by 1,2
)
※ 나중에 카테고리에 따른 월매출을 확인하고 싶으면 where절을 추가하면 된다.
-- 2.기준월매출 : 199706~199804만 남기고 0으로 처리
, cte_base_amount as(
select *
, case
when year||month between '199706' and '199804' then 월매출
else 0
end as 기준월매출
from cte_amount
order by 1,2
)
-- 3.매출 누계
, cte_agg as(
select *
, sum(기준월매출) over(order by year, month) as 매출누계
from cte_base_amount
)
-- 4. 전월 10개월 이동합계
, cte_pre10_sum as(
select *
, sum(월매출) over(order by year, month rows between 10 preceding and current row) as 이동합계
from cte_agg
)
--5. 최종결과
select year||'-'||month as 연월, 월매출, 매출누계, 이동합계
from cte_pre10_sum
where 기준월매출 != 0;
[✔️ 내가 짠 코드]
-- 1단계: cte 만들어주기 (지난 시간에 만든 것 사용)
with cte_products_sale as(
select o.order_id , o.customer_id , order_date
, to_char( o.order_date, 'yyyy-mm') as ym
, od.product_id , od.unit_price , od.unit_price 단가, od.quantity , od.discount
, od.unit_price * od.quantity * (1-od.discount) as 매출액
, c.category_id , c.category_name
, p.product_name , p.unit_price 고정단가, p.discontinued
, s.supplier_id , s.company_name , c2.country , c2.city
from orders o , order_details od , categories c , products p , suppliers s , customers c2
where o.customer_id = c2.customer_id
and o.order_id = od.order_id
and od.product_id = p.product_id
and p.category_id = c.category_id
and p.supplier_id = s.supplier_id
)
-- 2단계: 매출액 설정 만들기
, cte_sum as(
select ym
, round(sum(매출액)) 월별매출
, case when ym between '1997-06' and '1998-04' then
round(sum(매출액)) end 월별매출2
, round(sum(sum(매출액)) over (order by ym rows between 10 preceding and current row)) as 이동연계
from cte_products_sale
group by ym
order by ym
)
-- 3단계: 매출누계 만들기
, cte_cul as(
select ym, sum(월별매출) 월별매출
, round(sum(sum(월별매출2)) over (order by ym)) 매출누계
, sum(이동연계) 이동연계
from cte_sum
group by ym
)
-- 4단계: 원하는 기간 설정
select ym, 월별매출, 매출누계, 이동연계
from cte_cul
where ym between '1997-06' and '1998-04';
✔️ 매출누계를 원하는 기간에서 시작하는 부분이 어려웠는데 강사님께서 앞부분을 0으로 처리하면 된다고 힌트를 주셔서 case문을 활용하여 원하는 누계값을 구할 수 있었다!
※ 카테고리별 Z함수를 그리고 싶다면 2단계 where 절에 category_id = '숫자'를 입력해주면 된다!
✔️ 태블로로 시각화까지 해보았다. 처음에는 문제를 잘못 이해해서 연도별로 파티션을 걸어서 차트 모양이 이상하게 나왔는데, 문제를 다시 이해해서 시각화해보니 알맞은 Z모양이 나왔다. 어떻게 이런 개념을 발견했을까? 신기하다 👀
➡️ 단기적: 살짝 떨어졌다가 올라오고 있다. (상승중)
💡 실습하면서 알게 된 개념
(나중에는 방법을 알아서 사용하지 않았지만🙃)
[PostgreSQL] SELECT LIMIT ~ OFFSET 사용하기 (ft. 페이징 활용)
PostgreSQL에서 특히 페이징할때 많이 사용하는 LIMIT ~ OFFSET 에 대해 알아보자. ▷ 구문 SELECT * FROM [TABLE] LIMIT [NUM_A] OFFSET [NUM_B]; LIMIT는 개수를 제한하는것이며 OFFSET은 시작 위치를 지정해준다고 생각
mine-it-record.tistory.com
SELECT * FROM [TABLE] LIMIT [NUM_A] OFFSET [NUM_B];
- LIMIT: 개수를 제한하는 것
- OFFSET: 시작 위치를 지정하는 것
📍 그룹함수
- grouping sets 함수: 지정한 컬럼의 각 그룹별 집계
-- 1)
select category_name, product_name, round(sum(매출액)) 매출액
from cte_products_sale
group by grouping sets (1,2);
-- 2)
select category_name, product_name, company_name, country, city, round(sum(amount)) as 매출액
from cte_products_sale
group by grouping sets (1,2,3,(4,5),())
- 속성 별로 집계를 하고 싶을 때 grouping sets() 함수 사용
- ()는 전체 합계를 보여준다
📍 [미션] 연도, 분기, 월, 일별 매출액, 주문건수 집계
-- 연도, 분기, 월, 일, 매출액, 주문번호
, cte_select as(
select year||'년' as year
, year||'-'||quarter||'분기' as quarter
, year||'-'||month||'월' as month
, order_date as day
, amount, order_id
from cte_products_sale
)
-- 연도, 분기, 월, 날짜로 각각 그룹핑 하여 집계
, cte_grouping_sets as(
select year, quarter, month, day
, sum(매출액) as 총매출액
, count(distinct order_id) as 주문건수
from cte_select
group by grouping sets (year, quarter, month, day,())
order by 1,2,3,4
)
-- 연도별 매출액, 주문건수
, cte_year_amount_ordercnt as(
select year, 총매출액, 주문건수
from cte_grouping_sets
where year is not null
)
➡️ year을 quarter, month, day로 변경하면 각각을 확인할 수 있다.
-- 카테고리별 매출액
, cte_category_amount as(
select category_name, 총매출액
from cte_grouping_sets
where category_name is not null
)
-- 제품별 매출액
, cte_product_amount as(
select product_name, 총매출액
from cte_grouping_sets
where product_name is not null
)
select *
from cte_product_amount;
-- 공급국가 별 매출액
, cte_country_amount as(
select country, 매출액
from cte_grouping_sets
where country is not null and city is null -- city 주의
)
➡️ 4,5로 그룹핑 해주었기 때문에 country가 중복으로 나온다.
따라서 city is null 조건을 추가로 걸어주어야 한다.
-- (공급국가,공급도시) 별 매출액
, cte_country_city_amount as(
select country, city, 매출액
from cte_grouping_sets
where country is not null and city is not null -- city 주의
)
➡️ 둘 다 있는 값을 보기 위해선 두 값 모두 not null이어야 한다.
-- 전체 매출액, 주문건수
-- 방법1
, cte_all_amount as(
select 총매출액
from cte_grouping_sets
order by 1 desc
limit 1
)
-- 방법2
, cte_all_amount as(
select max(매출액) 매출액_all
from cte_grouping_sets
)
➡️ 모두 합쳐진 값은 가장 클 수밖에 없으므로 max로 구하는 것이 좋을 것 같다!
📍 rollup 함수
✔️ 단계별 소계 (소/중/대분류 별 소계할 때 유용)
-- 카테고리, 제품 별 매출액 소계
, cte_category_product_rollup as(
select category_name, product_name ,round(sum(amount)) 매출액
from cte_products_sale
group by rollup(1,2)
order by 1,2
)
-- 연도, 분기, 월, 일별 소계
, cte_orderdate_rollup as(
select year, quarter, month, day ,round(sum(amount)) 매출액
from cte_products_sale
group by rollup(year, quarter, month, day)
order by 1,2,3,4,5
)
➡️ year-quarter-month-day / year-quarter-month / year-quarter / year / 전체 소계를 나타낸다.
📍 CUBE 함수
➡️ 지정한 컬럼-그룹별 모든 조합에 대한 집계
: 가능한 모든 조합에 대한 grouping
, cte_cube as(
select year, quarter, round(sum(amount)) as 매출액
from cte_products_sale
group by cube(year, quarter)
order by 1,2
)
- year-month
- year
- month
📍 과제: 고객 속성, 구매 이력에 대한 집계 (group 함수 이용)
- 고객을 분석하기 위한 테이블을 만들어서 (고객 속성별, 고객 주문기간, 속한 국가 등) 그룹함수 적용하기?
- 결과 테이블 도출 -> 주석까지 달아서
나는 국가와 도시, 직급로 그룹함수를 적용해보았다.
-- country, city, contact_title grouping sets (매출액, 주문건수, 상품개수)
with cte_products_sale as(
select o.order_id , o.customer_id , order_date
, to_char( o.order_date, 'YYYY') as year
, to_char( o.order_date, 'mm') as month
, to_char( o.order_date, 'Q') as quarter
, to_char( o.order_date, 'YYYY-mm-dd') as day
, od.product_id , od.unit_price , od.unit_price 단가, od.quantity , od.discount
, od.unit_price * od.quantity * (1-od.discount) as amount
, c.category_id , c.category_name
, p.product_name , p.unit_price 고정단가, p.discontinued
, s.supplier_id , s.company_name , c2.country , c2.city , c2.contact_title
from orders o , order_details od , categories c , products p , suppliers s , customers c2
where o.customer_id = c2.customer_id
and o.order_id = od.order_id
and od.product_id = p.product_id
and p.category_id = c.category_id
and p.supplier_id = s.supplier_id
)
-- 국가, 도시, contact_title별 grouping sets
, cte_grouping_sets as(
select country, city, contact_title, round(sum(amount)) 매출액, count(distinct order_id) 주문건수, sum(quantity) 상품개수
from cte_products_sale
group by grouping sets (1,(1,2),3, ())
order by 1,2,3
)
-- 국가별 매출액, 주문건수, 상품개수
, cte_country as(
select country, 매출액, 주문건수, 상품개수
from cte_grouping_sets
where country is not null
)
-- 도시별 매출액, 주문건수, 상품개수
, cte_city as(
select city, 매출액, 주문건수, 상품개수
from cte_grouping_sets
where city is not null
)
-- contact_title별 매출액, 주문건수, 상품개수
, cte_contact_title as(
select contact_title, 매출액, 주문건수, 상품개수
from cte_grouping_sets
where contact_title is not null
)
-- 전체 매출액, 주문건수, 상품개수
, cte_all as(
select max(매출액) 매출액_all, max(주문건수) 주문건수_all, max(상품개수) 상품개수_all
from cte_grouping_sets
)
/* 국가별 매출액, 주문건수, 상품개수: cte_country
* 도시별 매출액, 주문건수, 상품개수: cte_city
* contact_title별 매출액, 주문건수, 상품개수: cte_contact_title
* 전체 매출액, 주문건수, 상품개수: cte_all */
select *
from cte_all
order by 2 desc;
-- country, city, contact_title rollup (매출액, 주문건수, 상품개수)
, cte_rollup as(
select country, city, contact_title, round(sum(amount)) 매출액, count(distinct order_id) 주문건수, sum(quantity) 상품개수
from cte_products_sale
group by rollup(1,2,3)
order by 1,2,3
)
select *
from cte_rollup;
-- country, city, contact_title cube (매출액, 주문건수, 상품개수)
, cte_rollup as(
select country, city, contact_title, round(sum(amount)) 매출액, count(distinct order_id) 주문건수, sum(quantity) 상품개수
from cte_products_sale
group by cube(1,2,3)
order by 1,2,3
)
select *
from cte_rollup;
* 유데미 큐레이션 바로가기 : https://bit.ly/3HRWeVL
* STARTERS 취업 부트캠프 공식 블로그 : https://blog.naver.com/udemy-wjtb
📌 본 후기는 유데미-웅진씽크빅 취업 부트캠프 4기 데이터분석/시각화 학습 일지 리뷰로 작성되었습니다.
'교육 > 유데미 스타터스 4기' 카테고리의 다른 글
[👩💻TIL 50일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.04.17 |
---|---|
유데미 스타터스 취업 부트캠프 4기 - 데이터분석/시각화(태블로) 10주차 학습 일지 (0) | 2023.04.14 |
[👩💻TIL 48일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.04.13 |
[👩💻TIL 47일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.04.12 |
[👩💻TIL 46일차 ] 유데미 스타터스 취업 부트캠프 4기 (0) | 2023.04.11 |