코딩테스트

[26.04.21 코테/회고(MySQL/Oracle)]-상품을 구매한 회원 비율 구하기

지니248 2026. 4. 21. 13:40

Lv5. 상품을 구매한 회원 비율 구하기 (MySQL)

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

 

내가 작성한 코드

-- 2021년 가입 전체 회원 수
WITH USERS_2021 AS (
    SELECT COUNT(*) AS TOTAL_USERS
    FROM USER_INFO
    WHERE YEAR(JOINED) = 2021
)
    
SELECT YEAR(O.SALES_DATE) AS YEAR
       ,MONTH(O.SALES_DATE) AS MONTH
       ,COUNT(DISTINCT O.USER_ID) AS PURCHASED_USERS
       ,ROUND(COUNT(DISTINCT O.USER_ID) / TOTAL_USERS, 1) AS PURCHASED_RATIO
FROM ONLINE_SALE O
JOIN USER_INFO U
  ON O.USER_ID = U.USER_ID
CROSS JOIN USERS_2021 T
WHERE YEAR(U.JOINED) = 2021
GROUP BY YEAR(O.SALES_DATE), MONTH(O.SALES_DATE)
ORDER BY YEAR, MONTH;

 

Oracle

-- 2021년 가입 전체 회원 수
WITH USERS_2021 AS (
    SELECT COUNT(*) AS TOTAL_USERS
    FROM USER_INFO
    WHERE EXTRACT(YEAR FROM JOINED) = 2021
)
    
SELECT EXTRACT(YEAR FROM O.SALES_DATE) AS YEAR
       ,EXTRACT(MONTH FROM O.SALES_DATE) AS MONTH
       ,COUNT(DISTINCT O.USER_ID) AS PURCHASED_USERS
       ,ROUND(COUNT(DISTINCT O.USER_ID) / TOTAL_USERS, 1) AS PURCHASED_RATIO
FROM ONLINE_SALE O
JOIN USER_INFO U
  ON O.USER_ID = U.USER_ID
CROSS JOIN USERS_2021 T
WHERE EXTRACT(YEAR FROM U.JOINED) = 2021
GROUP BY EXTRACT(YEAR FROM O.SALES_DATE), EXTRACT(MONTH FROM O.SALES_DATE), T.TOTAL_USERS
ORDER BY YEAR, MONTH;

 

문제 회고

1. CTE이름

- 이름의 첫 시작은 숫자로 시작하면 안된다는 사실을 다시 한번 확인할 수 있었다

2. Oracle의 GROUP BY절

- 처음에 MySQL의 코드와 같이 GROUP BY절에 T.TOTAL_USERS를 작성하지 않았다가 오류가 발생했다

- 이유는 집계 함수가 아닌 컬럼은 모두  GROUP BY에 있어야 한다는 엄격한 규칙 때문이었다

- SELECT절의 `ROUND(COUNT(DISTINCT O.USER_ID) / T.TOTAL_USERS, 1)` 에서 T.TOTAL_USERS는 

  일반 컬럼이므로 GROUP BY절에 추가해주어야 한다

3. DISTINCT를 활용한 중복 제거

- 처음에는 단순히 COUNT를 사용하려 했지만 한 회원이 같은 달에 여러 번 구매할 수 있다는 점을 고려해야 했다

- 따라서 실제 구매 건수가 아닌 구매한 회원 수를 구하기 위해 중복을 제거하는 DISTINCT를 사용하였다