취업준비/코딩테스트 문제 풀이

[프로그래머스 SQL 코딩테스트 연습] GROUP BY - 년, 월, 성별 별 상품 구매 회원 수 구하기

상급닌자연습생 2024. 4. 30. 01:54

🤔 문제

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

 

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

 

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

 

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

 

 

`USER_INFO` 테이블과 `ONLINE_SALE` 테이블에서 년, 월, 성별 별로 상품을 구매한 회원수를 집계하는 SQL문을 작성해주세요. 결과는 년, 월, 성별을 기준으로 오름차순 정렬해주세요. 이때, 성별 정보가 없는 경우 결과에서 제외해주세요.

 

 

 

예시

예를 들어 `USER_INFO` 테이블이 다음과 같고

`ONLINE_SALE` 테이블이 다음과 같다면

 

2022년 1월에 상품을 구매한 회원은 USER_ID 가 1(`GENDER`=1), 4(`GENDER`=0)인 회원들이고,

2022년 2월에 상품을 구매한 회원은 USER_ID 가 2(`GENDER`=NULL), 5(`GENDER`=1), 6(`GENDER`=1)인 회원들 이므로,

년, 월, 성별 별로 상품을 구매한 회원수를 집계하고, 년, 월, 성별을 기준으로 오름차순 정렬하면 다음과 같은 결과가 나와야 합니다.

 

 

 

 

 

 

 

 

 


💻 나의 풀이

SELECT YEAR(o.SALES_DATE) AS YEAR,
        MONTH(o.SALES_DATE) AS MONTH,
        u.GENDER,
        COUNT(DISTINCT u.USER_ID) AS USERS
FROM ONLINE_SALE o
LEFT JOIN USER_INFO u ON o.USER_ID = u.USER_ID
GROUP BY 1, 2, 3
HAVING u.GENDER IS NOT NULL
ORDER BY 1, 2, 3;

 

 

 

 

 

결과

 

 

 

 

 


✅ 핵심 포인트

1. DISTINCT

Q. 문제의 조건 중 "동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다."의 의미가 무엇일까?

 

`ONLINE_SALE` 테이블에 대해서 판매일, 회원ID, 상품ID 조합에 대해서는 고유한 판매 데이터만 존재한다고 했다.
하지만, `ONLINE_SALE` 테이블이 `USER_INFO` 테이블과 조인했을 경우 중복이 발생할 수 있다.

(`USER_ID`마다 `GENDER`는 다르게 설정될테니 제외한다 치면, 나머지 `AGE`나 `JOINED`로 인해 중복이 발생할 수 있을 것 같다)

 

실제로 비교를 위해 조인한 두 테이블에 대해서 `USER_ID`의 개수만 조회하는 코드를 실행해보았다.

 

1) `DISTINCT`를 사용하지 않고 개수를 조회했을 경우

SELECT COUNT(o.USER_ID) AS cnt
FROM ONLINE_SALE o
LEFT JOIN USER_INFO u
ON o.USER_ID = u.USER_ID

 

 

2) `DISTINCT`를 사용하여 중복을 제거한 후 개수를 조회했을 경우

SELECT COUNT(DISTINCT o.USER_ID) AS cnt
FROM ONLINE_SALE o
LEFT JOIN USER_INFO u
ON o.USER_ID = u.USER_ID

 

 

∴ 따라서 `USER_ID`의 개수를 셀 때는 아래의 코드와 같이 DISTINCT가 필요하다.

SELECT COUNT(DISTINCT u.USER_ID) AS USERS

 

 

 

 

 

 

 

 


🔗 References

[DISTINCT가 필요한 이유 참고]

https://gooreumwave.tistory.com/47

 

프로그래머스 Lv 4 - 년, 월, 성별 별 상품 구매 회원 수 구하기

습득한 점: 이전에는 테이블을 보이는데로 조인했다면, 지금은 테이블이 조인되었을 때의 형태를 머릿속으로 고려하면서 쿼리를 구성할 수 있게되었다. 문제: USER_INFO 테이블과 ONLINE_SALE 테이블

gooreumwave.tistory.com