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를 사용하였다
'코딩테스트' 카테고리의 다른 글
| [26.04.20 코테/회고(MySQL)]-Python 개발자 찾기 (0) | 2026.04.20 |
|---|---|
| [26.04.17 코테/회고(MySQL)]-한 해에 잡은 물고기 수 구하기 (1) | 2026.04.17 |
| [26.04.15 코테/회고(MySQL/Oracle)]-자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기 (0) | 2026.04.15 |
| [26.04.14 코테/회고(MySQL/Oracle)]-조건에 맞는 도서와 저자 리스트 출력하기 (0) | 2026.04.14 |
| [26.04.13 코테/회고(MySQL)-성분으로 구분한 아이스크림 총 주문량 (1) | 2026.04.13 |