SQL 고득점 Kit - GROUP BY 문제


✔️ 문제 설명

다음은 어느 의류 쇼핑몰에 가입한 회원 정보를 담은 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 테이블과 ONLINE_SALE 테이블에서 년, 월, 성별 별로 상품을 구매한 회원수를 집계하는 SQL문을 작성해주세요. 결과는 년, 월, 성별을 기준으로 오름차순 정렬해주세요. 이때, 성별 정보가 없는 경우 결과에서 제외해주세요. 👉 문제 보러가기


✔️ 문제 풀이

(1) Pseudo-Code

1. USER_INFO 테이블과 ONLINE_SALE 테이블을 JOIN으로 USER_ID를 기준으로 합친다.
2. 성별 정보가 없는 것은 가져오지 않는다. (IS NOT NULL)
3. 연도와 월은 DATE_FORMAT으로 분리하여 불러오고 GENDER은 그대로 가져온다.
4. 3번의 세 컬럼을 그룹바이로 묶는다.
5. 그룹바이한 컬럼들을 기준으로 USER_ID의 카운트값도 출력될 수 있도록 한다.
6. 데이터는 년, 월, 성별을 오름차순으로 정렬한다.

(2) 코드 작성

SELECT DATE_FORMAT(os.SALES_DATE, "%Y") AS YEAR, DATE_FORMAT(os.SALES_DATE, "%m") AS MONTH
     , ui.GENDER, COUNT(DISTINCT os.USER_ID) AS USERS
FROM ONLINE_SALE AS os
  INNER JOIN USER_INFO AS ui ON os.USER_ID = ui.USER_ID
WHERE GENDER IS NOT NULL
GROUP BY YEAR, MONTH, GENDER
ORDER BY YEAR ASC, MONTH ASC, GENDER ASC

(3) 코드 리뷰 및 회고

  • 이번 문제를 풀 때, USER_IDDISTINCT로 중복제거하여 가져와야 하는 점을 놓쳐서 시간이 많이 소요되었다.
  • 물품을 구매한 횟수가 여러번일 수 있고! 그렇게 되면 ONLINE_SALE 테이블에 USER_ID의 중복값이 있을 수 있다는 점을 간과했다.
  • 문제는 COUNT(os.USER_ID) -> COUNT(DISTINCT os.USER_ID)로 바꿈으로써 해결했다.
  • 앞으로 문제를 풀기 전에 JOIN 후에 어떤 테이블이 될지.. 생각해 보는 시간을 가져야겠다!


👩🏻‍💻개인 공부 기록용 블로그입니다
오류나 틀린 부분이 있을 경우 댓글 혹은 메일로 따끔하게 지적해주시면 감사하겠습니다.

댓글남기기