[SQL] 상품을 구매한 회원 비율 구하기

Hyunjun Kim·2024년 10월 28일
0

SQL

목록 보기
22/44

문제 : 상품을 구매한 회원 비율 구하기

문제 설명
다음은 어느 의류 쇼핑몰에 가입한 회원 정보를 담은 USER_INFO 테이블과 온라인 상품 판매 정보를 담은 ONLINE_SALE 테이블 입니다. USER_INFO 테이블은 아래와 같은 구조로 되어있으며 USER_ID, GENDER, AGE, JOINED는 각각 회원 ID, 성별, 나이, 가입일을 나타냅니다.

Column_nameTypeNullable
USER_IDINTEGERFALSE
GENDERTINYINT(1)TRUE
AGEINTEGERTRUE
JOINEDDATEFALSE

GENDER 컬럼은 비어있거나 0 또는 1의 값을 가지며 0인 경우 남자를, 1인 경우는 여자를 나타냅니다.

ONLINE_SALE 테이블은 아래와 같은 구조로 되어있으며 ONLINE_SALE_ID, USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE는 각각 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.

Column_nameTypeNullable
ONLINE_SALE_IDINTEGERFALSE
USER_IDINTEGERFALSE
PRODUCT_IDINTEGERFALSE
SALES_AMOUNTINTEGERFALSE
SALES_DATEDATEFALSE

동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.

문제
USER_INFO 테이블과 ONLINE_SALE 테이블에서 2021년에 가입한 전체 회원들 중 상품을 구매한 회원수와 상품을 구매한 회원의 비율(=2021년에 가입한 회원 중 상품을 구매한 회원수 / 2021년에 가입한 전체 회원 수)을 년, 월 별로 출력하는 SQL문을 작성해주세요. 상품을 구매한 회원의 비율은 소수점 두번째자리에서 반올림하고, 전체 결과는 년을 기준으로 오름차순 정렬해주시고 년이 같다면 월을 기준으로 오름차순 정렬해주세요.

문제 접근

SELECT * 
FROM (
    SELECT  YEAR(o.sales_date) YEAR ,MONTH(o.sales_date) MONTH, u.USER_ID
    FROM  (SELECT * FROM USER_INFO WHERE JOINED LIKE "2021%")  u
    LEFT JOIN ONLINE_SALE o
    ON u.USER_ID =o.USER_ID
    GROUP BY u.USER_ID, YEAR, MONTH) sub

실행 결과

YEARMONTHuser_id
1
202222
202212
3
202214
202225
6
202217
8
9
10
11
2022112
2022213
2022214
2022115
16

이런식으로 연도와 월 별 user_id의 COUNT 를 구했는데
어떻게 하면
각 연도, 월로 group by 해서
user_id 전체 DISTINCT 개수로 나누고싶은데 코드를 어떻게 짜면 좋을까 생각을 해보고 있었다.

내 풀이

SELECT YEAR(sales_date) YEAR, MONTH(sales_date) MONTH,
COUNT(DISTINCT o.USER_ID) PURCHASED_USERS,
ROUND(COUNT(DISTINCT o.USER_ID) / 
      (SELECT COUNT(*)
      FROM USER_INFO
      WHERE JOINED LIKE '2021%') , 1) PUCHASED_RATIO
FROM USER_INFO u JOIN ONLINE_SALE o
ON u.USER_ID = o.USER_ID
WHERE u.JOINED LIKE '2021%'
GROUP BY 1,2
ORDER BY 1,2

다른 사람 풀이

CTE 사용

WITH CNT AS(
    SELECT COUNT(DISTINCT USER_ID) NUM
    FROM USER_INFO
    WHERE YEAR(JOINED)='2021'
)

SELECT YEAR(SALES_DATE) YEAR,
MONTH(SALES_DATE) MONTH,
COUNT(DISTINCT USER_ID) PURCHASED_USERS,
ROUND(COUNT(DISTINCT USER_ID)/(SELECT COUNT(USER_ID) FROM USER_INFO WHERE YEAR(JOINED)='2021'),1) PURCHASED_RATIO
FROM ONLINE_SALE
JOIN USER_INFO USING(USER_ID)
WHERE YEAR(JOINED)='2021'
GROUP BY 1,2
ORDER BY 1,2


with을 사용한 풀이
>
```sql
WITH JOINED2021 AS (
    SELECT  *
    FROM    USER_INFO
    WHERE   YEAR(JOINED) = '2021'
)
SELECT      YEAR(B.SALES_DATE) YEAR, MONTH(B.SALES_DATE) MONTH,
            COUNT(DISTINCT B.USER_ID) PURCHASED_USERS,
            ROUND(COUNT(DISTINCT B.USER_ID) / (SELECT COUNT(*) FROM JOINED2021), 1) PURCHASED_RATIO
FROM        JOINED2021 A
INNER JOIN  ONLINE_SALE B ON A.USER_ID = B.USER_ID
GROUP BY    YEAR, MONTH
ORDER BY    YEAR, MONTH

쉬운 문제였지만 너무 어렵게 생각했던 것 같다.
SLECT 안에 SELECT 를 사용해서 테이블을 두번 불러와도 되는데
너무 JOIN 과정에서 해결하려고 하다보니 어려워졌던 부분이었다.

0개의 댓글