문제
https://solvesql.com/problems/revenue-pct-per-category/
https://solvesql.com/problems/revenue-pct-per-category/
solvesql.com
코드
gpt를 조져서 얻어낸 답안
with all_sale as ( -- 서브 카테고리 별로 매출액을 구한다
select
category,
sub_category,
sum(sales) as sales_sub_category
from records
group by category, sub_category
),
sales_with_totals as ( -- 서브 카테고리, 카테고리, 총 매출액을 구한다.
select
category,
sub_category,
round(sales_sub_category, 2) as sales_sub_category,
round(sum(sales_sub_category) over (partition by category), 2) as sales_category,
round(sum(sales_sub_category) over (), 2) as sales_total
from all_sale
)
select -- 서브 카테고리 / 카테고리, 서브 카테고리 / 총 매출의 비율을 구한다
category,
sub_category,
sales_sub_category,
sales_category,
sales_total,
round(sales_sub_category * 100 / sales_category, 2) as pct_in_category,
round(sales_sub_category * 100 / sales_total, 2) as pct_in_total
from sales_with_totals
이를 최적화해보겠다
with all_sale as ( -- 서브 카테고리 별 매출액을 구한다
select
category,
sub_category,
sum(sales) as sales_sub_category
from records
group by 1, 2
)
-- 서브 카테고리, 카테고리, 총 매출액을 구한다
-- 그 이후에 서브 카테고리 / 카테고리, 서브 카테고리 / 총 매출액 비율을 구한다
select
category,
sub_category,
round(sales_sub_category, 2) as sales_sub_category,
round(sum(sales_sub_category) over (partition by category), 2) as sales_category,
round(sum(sales_sub_category) over (), 2) as sales_total,
round(sales_sub_category * 100 / (sum(sales_sub_category) over (partition by category)), 2) as pct_in_category,
round(sales_sub_category * 100 / (sum(sales_sub_category) over ()), 2) as pct_in_total
from all_sale
짠 ~ !
SELECT
category,
sub_category,
ROUND(SUM(sales), 2) AS sales_sub_category,
ROUND(SUM(SUM(sales)) OVER (PARTITION BY category), 2) AS sales_category,
ROUND(SUM(SUM(sales)) OVER (), 2) AS sales_total,
ROUND(SUM(sales) * 100 / SUM(SUM(sales)) OVER (PARTITION BY category), 2) AS pct_in_category,
ROUND(SUM(sales) * 100 / SUM(SUM(sales)) OVER (), 2) AS pct_in_total
FROM records
GROUP BY 1, 2
ORDER BY 1, 2
^ 최종버전이다
gpt한테 물어봐서 짠 건데 gpt 천잰 듯 ..?
핵심 요지
1. sum(A) over (partition by B)
먼저 그룹화랑 partition 별로 합계 구하는 거는 한 select문 안에 동시에 할 수 없다! 가능하다
category와 sub_category 별로 그룹화를 해서 서브카테고리의 매출 합을 구한 값을 중간 결과로 저장한 후에
다음 select문에서에서 partition으로 서브 카테고리, 카테고리별 합계를 구해야 된다.
만약 over () -> 이렇게 비워놓으면 parition 없이 총 매출에 대한 합계가 들어간 컬럼을 만들 수 있다.
그렇다고 over()를 생략하면 전체 합계에 대한 단일행만 결과로 나오기 때문에 조심해야 된다.
category와 sub_category로 그룹화한 후에
sales_sub_category를 sum(sales)로 구한다.
그리고 나머지 카테고리 별 매출액과 전체 매출액은 sum() over (partition by)로 구한다.
2. over 절을 통해 계산된 값을 정의한 컬럼명은 같은 select 문 내에서 다시 참조할 수 없다

sales_cateogry는 over절을 사용해서 계산한 값인데
만약 sales_sub_category / sales_category 비율을 구하고 싶으면
같은 select문이 아닌 중간 결과를 저장한 후에
다음 select문에서 계산해야 한다.
서브쿼리를 사용하기 싫으면 분모에 들어갈 sales_category를 over절 함수로 대체해야 한다.
즉,
sales_sub_category / sales_category => X
sales_sub_category / (sum(sales_sub_category) over (partition by category)) => O
느낀 점
어렵다 ㅜ
이거를 10분 안에 어떻게 풀지 ... ㅎㅜ
'Tools > - SQL' 카테고리의 다른 글
| [SQL] 프로그래머스 예제 | 물고기 종류 별 대어 찾기 (0) | 2025.01.17 |
|---|---|
| [SQL] solvesql 세션 재정의하기 | lag () over (), 시간 차이 구하기 (0) | 2025.01.16 |
| [SQL] solvesql 가구 판매의 비중이 높았던 날 찾기 (0) | 2025.01.16 |
| [MySQL] Case문 | 문법과 간단한 예제 살펴보기 (0) | 2024.04.07 |
| [SQL] 프로그래머스 예제 | 그룹별 최대값 레코드 출력, 그룹별 레코드 count | 서브쿼리와 조인의 차이 (0) | 2024.03.15 |