본문 바로가기

TIL 통합/SQL

[프로그래머스] JOIN - 상품을 구매한 회원 비율 구하기

https://school.programmers.co.kr/learn/courses/30/lessons/131534

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

첫 번째 시도.

이렇게 할 경우 월별 카운트는 가능하나, 월별 비중을 출력하는 것은 다소 귀찮아 진다.       

SELECT       YEAR(SALES_DATE)
            ,MONTH(SALES_DATE)
            ,COUNT(USER_ID) AS PURCHASED_USERS
FROM         ONLINE_SALE
WHERE        USER_ID IN (
                            SELECT       USER_ID
                            FROM         USER_INFO
                            WHERE        JOINED LIKE '2021%' 
                        )
GROUP BY     1,2

 

 

 

얘도 오답. LEFT JOIN의 기준이 되는 테이블이 이미 구매를 한 이력이 있는 사람들만 출력하도록 되어 있어서 실패. 구매한 이력이 없는 사람들을 불러 올 수 있게끔 쿼리를 짜는 것이 포인트다.         

SELECT       YEAR(SALES_DATE) AS YEAER
            ,MONTH(SALES_DATE) AS MONTH
            ,COUNT(S.USER_ID) AS PURCHASED_USERS
            ,ROUND(COUNT(S.USER_ID)/COUNT(I.USER_ID), 1) AS PURCHASED_RATIO
FROM         ONLINE_SALE S
LEFT JOIN    USER_INFO I
USING        (USER_ID)
WHERE        JOINED LIKE '2021%' 
GROUP BY     1,2
ORDER BY     1, 2

 

 

 

아래가 정답.

회원당 구매이력이 여러번 있을 수도 있기에 DISTINCT를 해주는 것이 포인 

SELECT       YEAR(SALES_DATE) AS YEAR
            ,MONTH(SALES_DATE) AS MONTH
            ,COUNT(DISTINCT S.USER_ID) AS PURCHASED_USERS
            ,ROUND(COUNT(DISTINCT S.USER_ID)/(SELECT COUNT(USER_ID) FROM USER_INFO WHERE JOINED LIKE '2021%'), 1) AS PURCHASED_RATIO
FROM         ONLINE_SALE S
LEFT JOIN    USER_INFO I
USING        (USER_ID)
WHERE        JOINED LIKE '2021%'
GROUP BY     1, 2
ORDER BY     1, 2

 

 

 

아래는 예전에 했던 풀이 방식. 코드 내용은 별차이 없지만 지저분한 것이 흠.    

 

select year(s.sales_date) as year,
       month(s.sales_date) as month,
       count(distinct s.user_id) as purchased_users,
       round(count(distinct s.user_id)/(select count(distinct user_id) from user_info where joined like '2021%'),1) as purchased_ratio
from online_sale s join user_info i using(user_id)
where i.joined like '2021%'
group by 1, 2
order by 1, 2