문제 설명
다음은 어느 의류 쇼핑몰에 가입한 회원 정보를 담은
USER_INFO
테이블과 온라인 상품 판매 정보를 담은 ONLINE_SALE
테이블 입니다.USER_INFO
테이블은 아래와 같은 구조로 되어있으며 USER_ID
, GENDER
, AGE
, JOINED
는 각각 회원 ID, 성별, 나이, 가입일을 나타냅니다.Column name | Type | Nullable |
USER_ID | INTEGER | FALSE |
GENDER | TINYINT(1) | TRUE |
AGE | INTEGER | TRUE |
JOINED | DATE | FALSE |
GENDER
컬럼은 비어있거나 0 또는 1의 값을 가지며 0인 경우 남자를, 1인 경우는 여자를 나타냅니다.ONLINE_SALE
테이블은 아래와 같은 구조로 되어있으며, ONLINE_SALE_ID
, USER_ID
, PRODUCT_ID
, SALES_AMOUNT
, SALES_DATE
는 각각 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.Column name | Type | Nullable |
ONLINE_SALE_ID | INTEGER | FALSE |
USER_ID | INTEGER | FALSE |
PRODUCT_ID | INTEGER | FALSE |
SALES_AMOUNT | INTEGER | FALSE |
SALES_DATE | DATE | FALSE |
동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.
예시
예를 들어
USER_INFO
테이블이 다음과 같고USER_ID | GENDER | AGE | JOINED |
1 | 1 | 26 | 2021-06-01 |
2 | NULL | NULL | 2021-06-25 |
3 | 0 | NULL | 2021-06-30 |
4 | 0 | 31 | 2021-07-03 |
5 | 1 | 25 | 2021-07-09 |
6 | 1 | 33 | 2021-07-14 |
ONLINE_SALE
테이블이 다음과 같다면ONLINE_SALE_ID | USER_ID | PRODUCT_ID | SALES_AMOUNT | SALES_DATE |
1 | 1 | 54 | 1 | 2022-01-01 |
2 | 1 | 3 | 2 | 2022-01-25 |
3 | 4 | 34 | 1 | 2022-01-30 |
4 | 6 | 253 | 3 | 2022-02-03 |
5 | 2 | 31 | 2 | 2022-02-09 |
6 | 5 | 35 | 1 | 2022-02-14 |
7 | 5 | 57 | 1 | 2022-02-18 |
2022년 1월에 상품을 구매한 회원은
USER_ID
가 1(GENDER
=1), 4(GENDER
=0)인 회원들이고,2022년 2월에 상품을 구매한 회원은
USER_ID
가 2(GENDER
=NULL), 5(GENDER
=1), 6(GENDER
=1)인 회원들 이므로,년, 월, 성별 별로 상품을 구매한 회원수를 집계하고, 년, 월, 성별을 기준으로 오름차순 정렬하면 다음과 같은 결과가 나와야 합니다.
YEAR | MONTH | GENDER | USERS |
2022 | 1 | 0 | 1 |
2022 | 1 | 1 | 1 |
2022 | 2 | 1 | 2 |
코드
SELECT
YEAR(OS.SALES_DATE) AS YEAR,
MONTH(OS.SALES_DATE) AS MONTH,
UI.GENDER AS GENDER,
COUNT(DISTINCT UI.USER_ID) AS USERS
FROM
ONLINE_SALE OS
INNER JOIN
USER_INFO UI
ON
OS.USER_ID = UI.USER_ID
WHERE
UI.GENDER IS NOT NULL
GROUP BY
YEAR(OS.SALES_DATE), MONTH(OS.SALES_DATE), UI.GENDER
ORDER BY
YEAR(OS.SALES_DATE), MONTH(OS.SALES_DATE), UI.GENDER;

코드 - 중복제거 못함(문제 잘 못 읽음)
SELECT
YEAR(OS.SALES_DATE) AS YEAR,
MONTH(OS.SALES_DATE) AS MONTH,
UI.GENDER AS GENDER,
COUNT(*) AS USERS
FROM
ONLINE_SALE OS
INNER JOIN
USER_INFO UI
ON
OS.USER_ID = UI.USER_ID
WHERE
UI.GENDER IS NOT NULL
GROUP BY
YEAR(OS.SALES_DATE), MONTH(OS.SALES_DATE), UI.GENDER
ORDER BY
YEAR(OS.SALES_DATE), MONTH(OS.SALES_DATE), UI.GENDER;

문제의 핵심 요구사항 중 하나인 "상품을 구매한 회원수"를 집계할 때, 단순히
COUNT(*)
를 사용하면 중복된 회원이 포함될 수 있다는 점을 놓치신 것 같습니다.문제는 년, 월, 성별 별로
상품을 구매한 회원수
를 집계하는 것입니다. 한 회원이 한 달에 여러 번, 또는 여러 상품을 구매했더라도, 집계 시에는 1명으로 카운트되어야 합니다.작성하신 코드에서
COUNT(*)
대신 COUNT(DISTINCT UI.USER_ID)
를 사용하여 중복을 제거하면 정확한 정답이 됩니다.Share article