프로그래머스/SQL문제

[SQL문제] 상품을 구매한 회원 비율 구하기

뜽배 2022. 11. 12. 10:16
728x90
반응형

문제.

https://school.programmers.co.kr/learn/courses/30/lessons/131534

 

프로그래머스

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

programmers.co.kr

 

정답

SELECT 
TO_CHAR(B.SALES_DATE, 'YYYY') AS YEAR,
TO_NUMBER(TO_CHAR(B.SALES_DATE, 'MM')) AS MONTH,
COUNT(DISTINCT B.USER_ID) AS PUCHASED_USERS,
ROUND(COUNT(DISTINCT B.USER_ID) / A.COUNT, 1) AS PUCHASED_RATIO
FROM (
    SELECT A.*, COUNT(*) OVER() AS COUNT 
    FROM USER_INFO A
    WHERE TO_CHAR(A.JOINED, 'YYYY') = '2021') A 
    ,ONLINE_SALE B
WHERE A.USER_ID = B.USER_ID
GROUP BY TO_CHAR(B.SALES_DATE, 'YYYY'), TO_CHAR(B.SALES_DATE, 'MM'), A.COUNT
ORDER BY 1,2;

 

풀이

 

1. 조건

 

1-1.USER_INFO 테이블에서 2021년에 가입한 회원의 정보와 그 숫자를 찾을 것

1-2. '1-1'의 조건으로 ONLINE_SALE테이블과 조인해 '년월'별로 구매한 인원수와 그 비율을 구할 것

1-3. '1-2'를 통해 얻어진 결과로 년,월 순으로 정렬할 것

 

2. 풀이

2-1.

SELECT A.*, COUNT(*) OVER() AS COUNT 
FROM USER_INFO A
WHERE TO_CHAR(A.JOINED, 'YYYY') = '2021') A

FROM절의 첫번 째 인라인 뷰 A는 USER_INFO의 정보를 가져오며 WHERE절은 2021년에 가입한 인원을 필터하는 조건이고 SELECT절에 COUNT(*) OVER절은 그 인원수를 가져오는 문법이다.

이 문제에서 2021년에 가입한 회원수를 얻을려면 스칼라 서브쿼리를 사용하는 방법도 있겠지만 위와 같이 COUNT(*) OVER절을 사용하여 GROUP BY 와 다른 서브쿼리의 사용 없이 2021년도에 가입한 회원의 수를 받아 올 수 있다.

 

2-2.

WHERE A.USER_ID = B.USER_ID

WHERE절에서 사용한 조건은 A와 B의 조인 조건이다.

 

2-3.

SELECT 
TO_CHAR(B.SALES_DATE, 'YYYY') AS YEAR,
TO_NUMBER(TO_CHAR(B.SALES_DATE, 'MM')) AS MONTH,
COUNT(DISTINCT B.USER_ID) AS PUCHASED_USERS,
ROUND(COUNT(DISTINCT B.USER_ID) / A.COUNT, 1) AS PUCHASED_RATIO
    FROM (
        SELECT A.*, COUNT(*) OVER() AS COUNT 
        FROM USER_INFO A
        WHERE TO_CHAR(A.JOINED, 'YYYY') = '2021') A 
        ,ONLINE_SALE B
WHERE A.USER_ID = B.USER_ID
GROUP BY TO_CHAR(B.SALES_DATE, 'YYYY'), TO_CHAR(B.SALES_DATE, 'MM'), A.COUNT
ORDER BY 1,2;

SELECT절에서 YEAR와 MONTH를 통해 GROUP BY할 것을 염두해 둔다. 그리고 MONTH부분은 TO_NUMBER을 하지 않으면 틀렸다고 나온다. TO_CHAR이면 ORDER BY를 할 경우에 '11월' 이 '02'월 보다 앞에 있기때문에 틀리게 된다.

 

COUNT(DISTINCT B.USER_ID)를 통해 중복을 제거한 사용자의 인원 수를 가져올 수 있다.

ROUND함수를 통해 소수점 두번째 자리에서 반올림 하여 첫번째 자리만 남기도록 하였다.

 

마지막에 ORDER BY 1,2는 첫번째 컬럼, 두번째 컬럼 기준으로 오름차순 정렬하겠다는 의미이다.

728x90
반응형