[PostgreSQL초격차] _5_심화이론_서브쿼리(from절), 윈도우 함수, DDL

Hyejin Beck·2024년 1월 7일
0

데이터베이스(SQL)

목록 보기
8/40

서브쿼리

위치

: 서브쿼리는 from, where, group by, having 등에 사용할수 있지만,
실무에서는 거의 from 에서 사용합니다.

목적

: 하나의 SQL문으로 풀 수 없는, 조금 더 복잡한 데이터를 추출할 때

  • 하루동안 2개이상의 상품을 구매한 고객은 주로 어떤 상품을 구매했을까요?

    • 1 Depth : 하루동안 2개이상 상품을 구매한 고객 데이터
      • 2 Depth : 위의 고객들이 구매한 구매 데이터
  • A상품을 구매한 고객은 A상품 외에 추가로 어떤 상품을 구매했을까요?

    • 1 Depth : A상품 구매한 고객 데이터
      • 2 Depth : 위의 고객들이 구매한 구매 데이터
  • 하루동안 2개 이상의 상품을 구매한 고객의 성연령 분포는 어떠할까요?

    • 1 Depth : 하루동안 2개 이상의 상품을 구매한 고객 데이터
      • 2 Depth : 위의 고객들의 성별/연령별 데이터

예시 1

하루동안 2개 이상의 상품을 구매한 고객은 주로 어떤 상품을 구매했을까요?

먼저, 하루동안 2개이상의 상품을 구매한 고객 데이터를 확인합니다.

-- 하루동안 2개이상의 상품을 구매한 고객은 주로 어떤 상품을 구매했을까요? 
-- 1 Depth : 하루동안 2개이상의 상품을 구매한 고객 확인 
			-- online_order 테이블에서 고객별 구매한상품을 확인합니다. 
select oo.userid, count(distinct itemid ) as item_cnt 
from online_order oo 
join user_info ui on oo.userid = ui.userid 
group by 1 
having count(distinct itemid ) > 1 

이제 작성한 고객sql문을 inner join 을 해줍니다. (그래야 작성한 sql문 외에 다른 데이터까지 출력되지 않으니까요)

-- 2 Depth : 위의 고객은 주로 어떤 상품을 구매했을까? (카테고리3, 상품명, 금액별로 유저수와 매출액 )
select cate3, i.item_name , price , count(distinct oo.userid) as user_cnt , sum(gmv) as gmv 
from online_order oo 
join item i on oo.itemid = i.id 
join category c on i.category_id = c.id 
join ( 
	select oo.userid, count(distinct itemid ) as item_cnt 
	from online_order oo 
	join user_info ui on oo.userid = ui.userid 
	group by 1 
	having count(distinct itemid ) > 1 
)user_list on oo.userid  = user_list.userid 
group by 1, 2, 3 
order by 4 desc 

예시 2

A 상품을 구매한 고객은 A상품 외에 추가로 어떤 상품을 구매했을까요?

  • 1 Depth : A 상품을 구매한 고객 데이터
  • 2 Depth : 위의 고객에 한하여, 구매 데이터
-- A 상품을 구매한 고객은 A 상품 외에 추가로 어떤 상품을 구매했을까요? 
-- 1. 아이템명'블링블링 블라우스'를 구매한 고객id 
select distinct oo.userid 
from online_order oo 
join user_info ui on oo.userid = ui.userid 
join item i on oo.itemid = i.id 
where item_name = '블링블링 블라우스'

-- 2. 위의 고객Id에 한해서 구매한 목록 (아이템명, 유저 수)
select item_name, count(distinct oo.userid) as user_cnt 
from online_order oo 
join item i on oo.itemid  = i.id
join (
	select distinct oo.userid 
	from online_order oo 
	join user_info ui on oo.userid = ui.userid 
	join item i on oo.itemid = i.id 
	where item_name = '블링블링 블라우스'
) as user_list on oo.userid = user_list.userid 
group by 1 

예시 3

하루동안 2개이상의 상품을 구매한 고객의 성연령 분포는 어떠할까요?

  • 하루동안 2개 이상의 상품을 구매한 고객
    • 위의 고객의 성연령 분포
-- 하루동안 2개이상의 상품을 구매한 고객의 성연령 분포는 어떠할까요? 
-- 1. 하루동안 2개 이상의 상품을 구매한 고객
select oo.userid , count(distinct itemid) as item_cnt 
from online_order oo
join user_info ui on oo.userid = ui.userid 
group by 1 
having count(distinct itemid) >1 

-- 2. 위의 고객의 성연령 분포 
select 
	ui.gender
	, ui.age_band 
	, count(distinct oo.userid) as user_cnt 
	, count(distinct case when user_list.userid is not null then user_list.userid else null end) as user_cnt 
	, round(count(distinct case when user_list.userid is not null then user_list.userid else null end) :: numeric 
	/ count(distinct oo.userid) * 100, 1 ) as user_percent 
from online_order oo 
join user_info ui on oo.userid = ui.userid 
left join (
	select oo.userid , count(distinct itemid) as item_cnt 
	from online_order oo
	join user_info ui on oo.userid = ui.userid 
	group by 1 
	having count(distinct itemid) >1 
) as user_list on oo.userid = user_list.userid 
group by 1, 2 
order by 1,2 

윈도우 함수

목적

Group by 만으로는 원하는 계산이 안될 때 (구매비중, 성장률, 랭킹 등)
사실 굳이 SQL을 통해서 이러한 계산은 진행하지는 않는다고 합니다.

DDL

Data Definition Language 데이터 정의 언어

목적

DML

Data Maipulation Language 데이터 조작 언어

Truncate 와 Delete

Truncate는 한 번 하면 취소가 안됩니다! 롤백이 안됩니다!!

profile
데이터기반 스토리텔링을 통해 인사이트를 얻습니다.

0개의 댓글

관련 채용 정보