코딩테스트/SQL 코딩테스트

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

배또가또 2023. 12. 22. 22:21

출처 : https://school.programmers.co.kr/learn/courses/30/lessons/131532

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr



 

  • 문제 요구사항
    • USER_INFO 테이블과  ONLINE_SALE 데이터에서 년, 월, 성별 별로 구매한 회원 수를 집계
    • 결과는 년, 월, 성별별로 오름차순 정렬
    • 이 때 성별정보가 없는 경우는 결과에서 제외

DISTINCT 때문에 푸는데 애를 좀 먹었던 문제

 

두 테이블을 조인하고 유저 ID,  성별, 년,월(따로 SALES_DATE에서 추출하여 별도의 칼럼으로)에 해당하는 데이터를 IS NOT NULL 조건으로 서브 쿼리로 하여 데이터를 추출한 뒤 추출한 데이터를 테이블로 하여 USER_ID를 카운트해주는데 

 

이 때 횟수가 아니라, 회원 수 이기 때문에 USER_ID 앞에 DISTINCT를 입력해주어야 중복된 값이 빠지면서 회원의 수가 나오게 된다. 


1) Oracle

SELECT YEAR, 
       MONTH, 
       GENDER, 
       COUNT(DISTINCT USER_ID) AS USERS
FROM 
(
    SELECT U.USER_ID,
           EXTRACT(YEAR FROM O.SALES_DATE) AS YEAR,
           EXTRACT(MONTH FROM O.SALES_DATE) AS MONTH,
           U.GENDER
    FROM USER_INFO U INNER JOIN ONLINE_SALE O ON U.USER_ID=O.USER_ID
    WHERE U.GENDER IS NOT NULL
) A
GROUP BY YEAR, MONTH, GENDER
ORDER BY YEAR, MONTH, GENDER

 

기존에 하던대로 TO_CHAR(DATETIME, 'YYYY')  이런식으로 풀었더니 MySQL 정답과 출력 상태는 똑같은데

오답처리가 되길래  구글링을 통해 년,월,일을 추출하는 함수인 EXTRACT()를 사용하였더니 

정답 처리 되었다. 

 

정말 이런건 좀 통일 좀 해줬으면 처음부터 안 먹히던가...


2) MySQL

SELECT YEAR, 
       MONTH, 
       GENDER, 
       COUNT(DISTINCT USER_ID) AS USERS
FROM 
(
    SELECT U.USER_ID,
           DATE_FORMAT(O.SALES_DATE, '%Y') AS YEAR,
           DATE_FORMAT(O.SALES_DATE, '%m') AS MONTH,
           U.GENDER
    FROM USER_INFO U INNER JOIN ONLINE_SALE O ON U.USER_ID=O.USER_ID
    WHERE U.GENDER IS NOT NULL
) A
GROUP BY 1, 2, 3
ORDER BY 1, 2, 3