문제.
https://school.programmers.co.kr/learn/courses/30/lessons/131534
정답
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는 첫번째 컬럼, 두번째 컬럼 기준으로 오름차순 정렬하겠다는 의미이다.
'프로그래머스 > SQL문제' 카테고리의 다른 글
[SQL문제] 그룹별 조건에 맞는 식당 목록 출력하기 (0) | 2022.11.07 |
---|