[STARTERS 4๊ธฐ TIL] #48์ผ์ฐจ(23.04.13)


๐Ÿ“š ์˜ค๋Š˜์˜  ํ•™์Šต

์ œํ’ˆ/์นดํ…Œ๊ณ ๋ฆฌ ๋งค์ถœ ์ง€ํ‘œ ๋ถ„์„

1๏ธโƒฃ ์ „์ฒด ์ œํ’ˆ ๋งค์ถœ ์ˆœ์œ„ ๋ฐ ๋งค์ถœ ๋น„์œจ

2๏ธโƒฃ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ œํ’ˆ ๋‚ด์ถœ ์ˆœ์œ„ ๋ฐ ๋งค์ถœ ๋น„์œจ


๐Ÿ“Œ ์ž„์‹œ ํ…Œ์ด๋ธ” cte_products_sale ๐Ÿ“Œ

โœ… orders : ์ฃผ๋ฌธ๋ฒˆํ˜ธ, ๊ณ ๊ฐ๋ฒˆํ˜ธ, ์ฃผ๋ฌธ์ผ, ์—ฐ, ์›”, ์ผ, ๋ถ„๊ธฐ
โœ… order_details : ์ œํ’ˆ๋ฒˆํ˜ธ ํŒ๋งค๋‹จ๊ฐ€, ์ˆ˜๋Ÿ‰, ํ• ์ธ์œจ, ๋งค์ถœ์•ก
โœ… categories : ์นดํ…Œ๊ณ ๋ฆฌID, ์นดํ…Œ๊ณ ๋ฆฌ๋ช…
โœ… products : ์ œํ’ˆID, ์ œํ’ˆ๋ช…, ๋งˆ์Šคํ„ฐ๋‹จ๊ฐ€, ๋‹จ์ข…์—ฌ๋ถ€
โœ… suppliers : ๊ณต๊ธ‰์žID, ๊ณต๊ธ‰์ž๋ช…, ๊ตญ๊ฐ€, ๋„์‹œ

with cte_products_sale as(
select o.order_id , o.customer_id , o.order_date
	 , 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
	 , od.product_id , od.unit_price as ํŒ๋งค๋‹จ๊ฐ€ , od.quantity , od.discount , (od.unit_price * od.quantity * (1-od.discount)) as ๋งค์ถœ์•ก
	 , c.category_id , c.category_name 
	 , p.product_id , p.product_name , p.unit_price as ๋งˆ์Šคํ„ฐ๋‹จ๊ฐ€ , p.discontinued 
	 , s.supplier_id , s.company_name , s.country , s.city 
from orders o , order_details od , categories c , products p , suppliers s 
where 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 
)
select count(*)
from cte_products_sale;

๐Ÿ“Œ ์ œํ’ˆ๋ณ„ ๋งค์ถœ์•ก ์ˆœ์œ„ ๐Ÿ“Œ

with cte_products_sale as(
select o.order_id , o.customer_id , o.order_date
	 , 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
	 , od.product_id , od.unit_price as ํŒ๋งค๋‹จ๊ฐ€ , 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 as ๋งˆ์Šคํ„ฐ๋‹จ๊ฐ€ , p.discontinued 
	 , s.supplier_id , s.company_name , s.country , s.city 
from orders o , order_details od , categories c , products p , suppliers s 
where 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 
)
โœ… 1. ๋งค์ถœ์•ก ๊ณ„์‚ฐ
, cte_amount as (
select category_name, product_id, product_name, company_name, country
	 , sum(amount) as ๋งค์ถœ์•ก
from cte_products_sale
group by 1,2,3,4,5
order by product_id
)
โœ… 2. ์ˆœ์œ„, ์ „์ฒด ๋งค์ถœ์•ก ๊ณ„์‚ฐ
, cte_rank_totalamount as (
select *
	 , rank() over(order by ๋งค์ถœ์•ก desc) as ๋งค์ถœ์•ก์ˆœ์œ„
	 , sum(๋งค์ถœ์•ก) over() as ์ „์ฒด๋งค์ถœ
from cte_amount
)
โœ… 3. ๋งค์ถœ ๋น„์œจ ๊ณ„์‚ฐ
, cte_radio as (
select *
	 , ๋งค์ถœ์•ก / ์ „์ฒด๋งค์ถœ * 100 as ๋งค์ถœ๋น„์œจ
from cte_rank_totalamount
)
โœ… 4. ์ตœ์ข…ํ…Œ์ด๋ธ”
select category_name, product_id, product_name, company_name, country, ๋งค์ถœ์•ก, ๋งค์ถœ์•ก์ˆœ์œ„
	 ,round(๋งค์ถœ๋น„์œจ::numeric ,2)::varchar(10)||'%' as ๋งค์ถœ๋น„์œจ 
from cte_radio
order by 1;

 

 

ABC ๋ถ„์„

ํ†ต๊ณ„์  ๋ฐฉ๋ฒ•์— ์˜ํ•ด ๊ด€๋ฆฌ๋Œ€์ƒ์„ A, B, C ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„๊ณ ,

๋จผ์ € A๊ทธ๋ฃน์„ ์ตœ์ค‘์  ๊ด€๋ฆฌ๋Œ€์ƒ์œผ๋กœ ์„ ์ •ํ•˜์—ฌ ๊ด€๋ฆฌ๋…ธ๋ ฅ์„ ์ง‘์ค‘ํ•จ์œผ๋กœ์จ ๊ด€๋ฆฌํšจ๊ณผ๋ฅผ ๋†’์ด๋ ค๋Š” ๋ถ„์„๋ฐฉ๋ฒ•.

 

ABC๋ถ„์„

ํ†ต๊ณ„์  ๋ฐฉ๋ฒ•์— ์˜ํ•ด ๊ด€๋ฆฌ๋Œ€์ƒ์„ A, B, C ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ„๊ณ , ๋จผ์ € A๊ทธ๋ฃน์„ ์ตœ์ค‘์  ๊ด€๋ฆฌ๋Œ€์ƒ์œผ๋กœ ์„ ์ •ํ•˜์—ฌ ๊ด€๋ฆฌ๋…ธ๋ ฅ์„ ์ง‘์ค‘ํ•จ์œผ๋กœ์จ ๊ด€๋ฆฌํšจ๊ณผ๋ฅผ ๋†’์ด๋ ค๋Š” ๋ถ„์„๋ฐฉ๋ฒ•. ์ด๋Š” "๊ทนํžˆ ์†Œ์ˆ˜์˜ ์š”์ธ์— ์˜ํ•ด

terms.naver.com

 

๐Ÿ“Œ ABC ํ…Œ์ŠคํŠธ ๐Ÿ“Œ

with cte_products_sale as(
select o.order_id , o.customer_id , o.order_date
	 , 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
	 , od.product_id , od.unit_price as ํŒ๋งค๋‹จ๊ฐ€ , 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 as ๋งˆ์Šคํ„ฐ๋‹จ๊ฐ€ , p.discontinued 
	 , s.supplier_id , s.company_name , s.country , s.city 
from orders o , order_details od , categories c , products p , suppliers s 
where 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 
)
โœ… 1. ์ œํ’ˆ๋ณ„ ๋งค์ถœ์•ก
, cte_amount as (
select product_id , product_name
	 , sum(amount) as ๋งค์ถœ์•ก
from cte_products_sale
group by 1, 2
order by product_id
)
โœ… 2. ๊ตฌ์„ฑ๋น„
, cte_ratio as (
select *
	 , sum(๋งค์ถœ์•ก) over() as ์ „์ฒด๋งค์ถœ์•ก
	 , ๋งค์ถœ์•ก/sum(๋งค์ถœ์•ก) over()*100 as ๊ตฌ์„ฑ๋น„
from cte_amount
)
โœ… 3.๊ตฌ์„ฑ๋น„ ๋ˆ„๊ณ„
, cte_ratio_agg as (
select *
	 , sum(๊ตฌ์„ฑ๋น„) over (order by ๊ตฌ์„ฑ๋น„ desc) as ๊ตฌ์„ฑ๋น„๋ˆ„๊ณ„
from cte_ratio
order by ๊ตฌ์„ฑ๋น„ desc
)
โœ… 4. ๋“ฑ๊ธ‰
, cte_class as (
select *
	 , case 
	 	when ๊ตฌ์„ฑ๋น„๋ˆ„๊ณ„ <= 70 then 'A'
	 	when ๊ตฌ์„ฑ๋น„๋ˆ„๊ณ„ <= 90 then 'B'
	 	else 'C'
	 end as ๋“ฑ๊ธ‰
from cte_ratio_agg
order by ๊ตฌ์„ฑ๋น„ desc
)
โœ… ์ตœ์ข… ํ…Œ์ด๋ธ”
select * from cte_class;

 

 

Pivot
๐Ÿ“Œ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ˆœ์œ„๋ฅผ ํ”ผ๋ฒ—ํ•˜๊ธฐ ๐Ÿ“Œ

with cte_products_sale as(
select o.order_id , o.customer_id , o.order_date
	 , 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
	 , od.product_id , od.unit_price as ํŒ๋งค๋‹จ๊ฐ€ , 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 as ๋งˆ์Šคํ„ฐ๋‹จ๊ฐ€ , p.discontinued 
	 , s.supplier_id , s.company_name , s.country , s.city 
from orders o , order_details od , categories c , products p , suppliers s 
where 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 
)
โœ… 1. ๋งค์ถœ์•ก ๊ณ„์‚ฐ
, cte_amount as (
select category_name, product_id, product_name, company_name, country
	 , sum(amount) as ๋งค์ถœ์•ก
from cte_products_sale
group by 1,2,3,4,5
order by product_id
)
โœ… 2. ์ˆœ์œ„
, cte_rank_totalamount_category as (
select *
	 , rank() over(partition by category_name order by ๋งค์ถœ์•ก desc) as ๋งค์ถœ์•ก์ˆœ์œ„
from cte_amount
)
โœ… 3. 3์œ„๊นŒ์ง€ ๋ฝ‘๊ธฐ
, cte_rank_top3 as (
select *
from cte_rank_totalamount_category
where ๋งค์ถœ์•ก์ˆœ์œ„ between 1 and 3
)
โœ… 4. ํ”ผ๋ด‡ํ•˜๊ธฐ
select category_name
	 โœ… 1์œ„ ์—ด
	 , max(case when ๋งค์ถœ์•ก์ˆœ์œ„ = 1 then product_name end) as "1์œ„"
	 โœ… 2์œ„ ์—ด
 	 , max(case when ๋งค์ถœ์•ก์ˆœ์œ„ = 2 then product_name end) as "2์œ„"
	 โœ… 3์œ„ ์—ด
 	 , max(case when ๋งค์ถœ์•ก์ˆœ์œ„ = 3 then product_name end) as "3์œ„"
from cte_rank_top3
group by 1;

 

๐Ÿ“Œ ๋งค์ถœ์•ก ์ˆœ์œ„ ๋ณ„๋กœ ์นดํ…Œ๊ณ ๋ฆฌ ํ”ผ๋ฒ—ํ•˜๊ธฐ ๐Ÿ“Œ

with cte_products_sale as(
select o.order_id , o.customer_id , o.order_date
	 , 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
	 , od.product_id , od.unit_price as ํŒ๋งค๋‹จ๊ฐ€ , 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 as ๋งˆ์Šคํ„ฐ๋‹จ๊ฐ€ , p.discontinued 
	 , s.supplier_id , s.company_name , s.country , s.city 
from orders o , order_details od , categories c , products p , suppliers s 
where 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 
)
โœ… 1. ๋งค์ถœ์•ก ๊ณ„์‚ฐ
, cte_amount as (
select category_name, product_id, product_name, company_name, country
	 , sum(amount) as ๋งค์ถœ์•ก
from cte_products_sale
group by 1,2,3,4,5
order by product_id
)
โœ… 2. ์ˆœ์œ„
, cte_rank_totalamount_category as (
select *
	 , rank() over(partition by category_name order by ๋งค์ถœ์•ก desc) as ๋งค์ถœ์•ก์ˆœ์œ„
from cte_amount
)
โœ… 3. ํ”ผ๋ด‡, null๊ฐ’ ์ฒ˜๋ฆฌ
select ๋งค์ถœ์•ก์ˆœ์œ„
	 , coalesce(max(case when category_name = 'Beverages' then product_name end), '') as "Beverages"
	 , coalesce(max(case when category_name = 'Condiments' then product_name end), '') as "Condiments"
	 , coalesce(max(case when category_name = 'Confections' then product_name end), '') as "Confections"
	 , coalesce(max(case when category_name = 'Dairy Products' then product_name end), '') as "Dairy Products"
	 , coalesce(max(case when category_name = 'Grains/Cereals' then product_name end), '') as "Grains/Cereals"
	 , coalesce(max(case when category_name = 'Meat/Poultry' then product_name end), '') as "Meat/Poultry"
	 , coalesce(max(case when category_name = 'Produce' then product_name end), '') as "Produce"
	 , coalesce(max(case when category_name = 'Seafood' then product_name end), '') as "Seafood"
from cte_rank_totalamount_category
group by 1
order by 1;

 

 

 

๐Ÿ“ ์˜ค๋Š˜์˜ ๊ณผ์ œ

1๏ธโƒฃ ์ „์ฒด ํŒ๋งค ์ˆ˜๋Ÿ‰ ํƒ‘10 cte_products_quantity
-- products : product_id, product_name,
-- order_details : quantity, unit_price, discount, ๋งค์ถœ์•ก
-- categories : category_name

with cte_products_quantity as (
select p.product_id , p.product_name 
	 , od.quantity , od.unit_price , od.discount , od.quantity * od.unit_price * (1-od.discount) as amount
	 , c.category_name 
from products p , order_details od , categories c 
where p.product_id = od.product_id 
  and p.category_id = c.category_id 
)
-- 1. ์ œํ’ˆ๋ณ„๋กœ ๊ทธ๋ฃจํ•‘
, cte_products_quantity_total as (
select product_id, product_name
	 , sum(quantity) as total_quantity 
	 , sum(amount) as total_sales 
	 , max(category_name) as category_name
from cte_products_quantity
group by product_id , product_name )
-- 2. ์ˆœ์œ„ ์ถ”๊ฐ€ ๋ฐ 10์œ„๊นŒ์ง€ ์ถ”์ถœ
 , cte_products_rank as (
select rank() over (order by total_quantity desc), *
from cte_products_quantity_total
limit 10)
select * from cte_products_rank;

 

2๏ธโƒฃ ๊ตญ๊ฐ€๋ณ„ ํŒ๋งค์ˆ˜๋Ÿ‰ ํƒ‘5 cte_country_sales
-- suppliers : country
-- products : product_id, product_name,
-- order_details : quantity

with cte_country_sales as (
select c.country , p.product_id , p.product_name 
	 , od.quantity , od.unit_price , od.discount , od.quantity * od.unit_price * (1-od.discount) as amount
from products p , order_details od , orders o, customers c 
where p.product_id = od.product_id 
  and od.order_id = o.order_id
  and o.customer_id = c.customer_id 
order by c.country)
-- 1. ๊ตญ๊ฐ€, ์ œํ’ˆ ๋ณ„๋กœ ๊ทธ๋ฃจํ•‘
, cte_country_product as (
select country, product_id, product_name
	 , sum(quantity) as total_quantity
	 , sum(amount) as total_sales
from cte_country_sales
group by country, product_id, product_name
order by country, product_id
)
-- 2. ๊ตญ๊ฐ€๋ณ„ ํŒ๋งค์ˆ˜๋Ÿ‰ ์ˆœ์œ„ ์ปฌ๋Ÿผ ์ถ”๊ฐ€
, cte_country_rank as (
select rank() over (partition by country order by total_quantity desc, total_sales desc) as rank, *
from cte_country_product)
-- 3. ํ”ผ๋ด‡ ์ง„ํ–‰, ๊ตญ๊ฐ€ ์ด ๋งค์ถœ์•ก ์ปฌ๋Ÿผ ์ถ”๊ฐ€
, cte_country_pivot as (
select country
	 , max(case when rank = 1 then product_name end) as rank1
	 , max(case when rank = 2 then product_name end) as rank2
	 , max(case when rank = 3 then product_name end) as rank3
	 , max(case when rank = 4 then product_name end) as rank4
	 , max(case when rank = 5 then product_name end) as rank5
	 , sum(total_sales) as total_total_sales
from cte_country_rank
group by country
)
-- 4. ์ด ๋งค์ถœ์•ก ์ˆœ์œผ๋กœ ์ •๋ ฌ
, cte_country_table as (
select country, rank1, rank2, rank3, rank4, rank5
from cte_country_pivot
order by total_total_sales desc)
 select * from cte_country_table;

 

3๏ธโƒฃ 1997๋…„ ๋ถ„๊ธฐ๋ณ„ ํŒ๋งค์ˆ˜๋Ÿ‰ ํƒ‘10 cte_quarter_sales
-- products : product_id, product_name,
-- order_details : quantity
-- orders : order_date, ์—ฐ๋„, ๋ถ„

with cte_quarter_sales as (
select p.product_id , p.product_name 
	 , od.quantity , od.unit_price , od.discount , od.quantity * od.unit_price * (1-od.discount) as amount
	 , to_char(order_date, 'YYYY') as year
	 , to_char(order_date, 'q') as quarter
from order_details od , products p , orders o 
where od.product_id = p.product_id 
  and od.order_id = o.order_id 
)
-- 1. 1997๋…„ ๋ฐ์ดํ„ฐ ์ถ”์ถœ
, cte_1997_sales as (
select *
from cte_quarter_sales
where year = '1997')
-- 2. ๊ทธ๋ฃจํ•‘
, cte_group as (
select year, quarter, product_name
	 , sum(quantity) as total_quantity 
	 , sum(amount) as total_amount
from cte_1997_sales
group by year, quarter, product_name
)
-- 3. ๋ถ„๊ธฐ๋ณ„ ํŒ๋งค์ˆ˜๋Ÿ‰ ์ˆœ์œ„ ์„ ์ •
, cte_1997_rank as (
select rank() over (partition by quarter order by total_quantity desc, total_amount desc) as rank
	 , *
from cte_group
)
-- 4. ํ”ผ๋ด‡
, cte_1997_pivot as (
select rank 
	 , max(case when quarter = '1' then product_name end) as "1997-1๋ถ„๊ธฐ"
	 , max(case when quarter = '2' then product_name end) as "1997-2๋ถ„๊ธฐ"
	 , max(case when quarter = '3' then product_name end) as "1997-3๋ถ„๊ธฐ"
	 , max(case when quarter = '4' then product_name end) as "1997-4๋ถ„๊ธฐ"
from cte_1997_rank
group by rank
limit 10
)
select * from cte_1997_pivot;

 

4๏ธโƒฃ 1997๋…„ ๋ถ„๊ธฐ๋ณ„ ํŒ๋งค์ˆ˜๋Ÿ‰ ์ˆœ์œ„๋ณ€ํ™” cte_quarter_sales
-- products : product_id, product_name,
-- order_details : quantity
-- orders : order_date, ์—ฐ๋„, ๋ถ„

with cte_quarter_sales as (
select p.product_id , p.product_name 
	 , od.quantity , od.unit_price , od.discount , od.quantity * od.unit_price * (1-od.discount) as amount
	 , to_char(order_date, 'YYYY') as year
	 , to_char(order_date, 'q') as quarter
from order_details od , products p , orders o 
where od.product_id = p.product_id 
  and od.order_id = o.order_id 
)
-- 1. ๋ถ„๊ธฐ ๋„˜๋ฒ„๋ง
, cte_quarter_no as (
select *
	, case 
	when year = '1996' and quarter = '4' then 1
	when year = '1997' and quarter = '1' then 2  
	when year = '1997' and quarter = '2' then 3 
	when year = '1997' and quarter = '3' then 4 
	when year = '1997' and quarter = '4' then 5 end as no
from cte_quarter_sales
)
-- 2. ํ•„์š” ๋ถ„๊ธฐ๋งŒ ์ถ”์ถœ
, cte_need_year as (
select *
from cte_quarter_no
where not no isnull 
)
-- 3. ๊ทธ๋ฃจํ•‘
, cte_group as (
select no, year, quarter, product_name
	 , sum(quantity) as total_quantity
	 , sum(amount) as total_sales
from cte_need_year
group by no, year, quarter, product_name
order by no, year, quarter, product_name
)
-- 4. ์ˆœ์œ„
, cte_rank as (
select rank () over (partition by no order by total_quantity desc, total_sales desc), *
from cte_group)
-- 5. ์ˆœ์œ„๋ณ€ํ™” ์‚ฐ์ถœ
, cte_lag as (
select *, lag(rank,1) over(partition by product_name order by no)-rank as "์ˆœ์œ„๋ณ€ํ™”"
from cte_rank)
-- 6. ํ”ผ๋ฒ— ์ง„ํ–‰
, cte_pivot as (
select rank
	 , max(case when no = 2 then product_name end) as "1997๋…„ 1๋ถ„๊ธฐ"
	 , max(case when no = 2 then ์ˆœ์œ„๋ณ€ํ™” end) as "์ˆœ์œ„๋ณ€ํ™”"
	 , max(case when no = 3 then product_name end) as "1997๋…„ 2๋ถ„๊ธฐ"
	 , max(case when no = 3 then ์ˆœ์œ„๋ณ€ํ™” end) as "์ˆœ์œ„๋ณ€ํ™”"
	 , max(case when no = 4 then product_name end) as "1997๋…„ 3๋ถ„๊ธฐ"
	 , max(case when no = 4 then ์ˆœ์œ„๋ณ€ํ™” end) as "์ˆœ์œ„๋ณ€ํ™”"
	 , max(case when no = 5 then product_name end) as "1997๋…„ 4๋ถ„๊ธฐ"
	 , max(case when no = 5 then ์ˆœ์œ„๋ณ€ํ™” end) as "์ˆœ์œ„๋ณ€ํ™”"
from cte_lag
group by rank
order by rank
limit 10
)
select * from cte_pivot;