[programmers] SQL Lv. 4 - 저자 별 카테고리 별 매출액 집계하기

2025. 1. 13. 13:59·Algorithm Solving/SQL

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

문제 설명
다음은 어느 한 서점에서 판매중인 도서들의 도서 정보(BOOK), 저자 정보(AUTHOR) 테이블입니다.

BOOK 테이블은 각 도서의 정보를 담은 테이블로 아래와 같은 구조로 되어있습니다.


AUTHOR 테이블은 도서의 저자의 정보를 담은 테이블로 아래와 같은 구조로 되어있습니다.


BOOK_SALES 테이블은 각 도서의 날짜 별 판매량 정보를 담은 테이블로 아래와 같은 구조로 되어있습니다.

 

문제
2022년 1월의 도서 판매 데이터를 기준으로 저자 별, 카테고리 별 매출액(TOTAL_SALES = 판매량 * 판매가) 을 구하여, 저자 ID(AUTHOR_ID), 저자명(AUTHOR_NAME), 카테고리(CATEGORY), 매출액(SALES) 리스트를 출력하는 SQL문을 작성해주세요.
결과는 저자 ID를 오름차순으로, 저자 ID가 같다면 카테고리를 내림차순 정렬해주세요.

 


풀이

틀린 풀이 🥲

SELECT 
    AUTHOR_ID, AUTHOR_NAME, CATEGORY,
    (PRICE * SUM(SUM_SALES)) AS TOTAL_SALES
FROM 
(
    SELECT 
        B.BOOK_ID, B.PRICE,
        A.AUTHOR_ID, A.AUTHOR_NAME, 
        B.CATEGORY,
        DATE_FORMAT(BS.SALES_DATE, '%Y-%m') AS SALES_YEARMONTH, 
        SUM(SALES) AS SUM_SALES
    FROM BOOK B
    JOIN BOOK_SALES BS ON B.BOOK_ID = BS.BOOK_ID
    JOIN AUTHOR A ON B.AUTHOR_ID = A.AUTHOR_ID
    GROUP BY SALES_YEARMONTH, B.BOOK_ID
) SUB
WHERE SALES_YEARMONTH = '2022-01'
GROUP BY AUTHOR_ID, CATEGORY
ORDER BY AUTHOR_ID, CATEGORY DESC

틀린 이유:

합계 계산 위치가 틀렸다.

서브 쿼리 `SUB`에서 `SUM(SALES)`로 `SUM_SALES`를 집계했는데,

최상위 쿼리에서 `SUM(SUM_SALES)`를 다시 수행하면서 `PRICE`와 곱하는 로직이 잘못됐다.

최상위 쿼리에서는 개별 책의 `PRICE`를 알 수 없기 때문이다.

(개별 책(`BOOK_ID`)별로 그룹짓는게 아니라, `AUTHOR_ID`와 `CATEGORY`로 그룹짓기 때문에 `PRICE`가 올바르게 매칭되지 않음)

 

정상 작동하도록 수정:

총 매출액은 개별 책의 판매량과 가격을 곱한 값을 합산해야 한다!

➡️ 서브 쿼리에서 개별 책마다 매출액을 계산하고 이를 최상위 쿼리에서 카테고리별로 합산하도록 함.

 

서브쿼리에서는 `GROUP BY B.BOOK_ID`가 되어있고, `B.BOOK_ID`(개별 책)마다 `PRICE`가 올바르게 매칭되어 있다.

따라서, 매출액을 구할 때 `(SUM(SALES) * B.PRICE) AS SUM_SALES`가 가능하다.

그리고 최상위 쿼리에서는 `SUM(SUM_SALES)`로 `TOTAL_SALES`(총 매출액)를 계산하도록 한다.

 


제출

SELECT 
    SUB.AUTHOR_ID, A.AUTHOR_NAME, SUB.CATEGORY,
    SUM(SUB.SUM_SALES) AS TOTAL_SALES
FROM 
(
    SELECT 
        B.BOOK_ID, B.CATEGORY, B.AUTHOR_ID, 
        (SUM(SALES) * B.PRICE) AS SUM_SALES
    FROM BOOK B
    JOIN BOOK_SALES BS ON B.BOOK_ID = BS.BOOK_ID
    WHERE BS.SALES_DATE BETWEEN '2022-01-01' AND '2022-01-31'
    GROUP BY 
        B.BOOK_ID, B.CATEGORY, B.AUTHOR_ID
    ORDER BY B.BOOK_ID
) SUB
JOIN AUTHOR A ON SUB.AUTHOR_ID = A.AUTHOR_ID
GROUP BY A.AUTHOR_ID, SUB.CATEGORY
ORDER BY A.AUTHOR_ID, SUB.CATEGORY DESC

 

+ 틀린코드에서 매출액 계산만 수정해도 정답 처리 된다. (틀린 코드에서도 조인 조건은 맞았기 때문에)

하지만 `GROUP BY`와 `SELECT` 컬럼이 일치하지 않기 때문에 위의 제출 코드가 더 옳아?보인다.

(일부 데이터베이스에서는 GROUP BY 절에 포함되지 않은 컬럼은 허용되지 않는다.)

SELECT 
    AUTHOR_ID, AUTHOR_NAME, CATEGORY,
    SUM(SUM_SALES) AS TOTAL_SALES
FROM 
(
    SELECT 
        B.BOOK_ID, 
        A.AUTHOR_ID, A.AUTHOR_NAME, 
        B.CATEGORY,
        DATE_FORMAT(BS.SALES_DATE, '%Y-%m') AS SALES_YEARMONTH, 
        (SUM(SALES) * B.PRICE) AS SUM_SALES
    FROM BOOK B
    JOIN BOOK_SALES BS ON B.BOOK_ID = BS.BOOK_ID
    JOIN AUTHOR A ON B.AUTHOR_ID = A.AUTHOR_ID
    GROUP BY SALES_YEARMONTH, B.BOOK_ID
) SUB
WHERE SALES_YEARMONTH = '2022-01'
GROUP BY AUTHOR_ID, CATEGORY
ORDER BY AUTHOR_ID, CATEGORY DESC

 


응용

제출 코드 1은 `WHERE`절에서 `BETWEEN`으로 날짜를 직접 비교한다.

제출 코드 2는 위의 설명처럼 `GROUP BY`와 `SELECT` 컬럼이 일치하지 않는다.

 

2022년 1월의 경우 뿐만 아니라 YYYY-mm 기간에 대한 저자와 카테고리별 매출액을 출력하는 쿼리를 제출코드 1과 2의 장점을 합쳐서 작성해보았다.

SELECT 
    A.AUTHOR_ID, A.AUTHOR_NAME, 
    SUB.CATEGORY, SUB.SALES_YEARMONTH,
    SUM(SUM_SALES) AS TOTAL_SALES
FROM 
(
    SELECT 
        B.BOOK_ID, 
        B.CATEGORY,
        B.AUTHOR_ID,
        (SUM(SALES) * B.PRICE) AS SUM_SALES,
        DATE_FORMAT(BS.SALES_DATE, '%Y-%m') AS SALES_YEARMONTH
    FROM BOOK B
    JOIN BOOK_SALES BS ON B.BOOK_ID = BS.BOOK_ID
    GROUP BY SALES_YEARMONTH, B.BOOK_ID, B.CATEGORY, B.AUTHOR_ID
) SUB
JOIN AUTHOR A ON SUB.AUTHOR_ID = A.AUTHOR_ID
-- WHERE SALES_YEARMONTH = '2022-01'
GROUP BY AUTHOR_ID, CATEGORY, SALES_YEARMONTH
ORDER BY SALES_YEARMONTH, AUTHOR_ID, CATEGORY DESC

2022-01 기간 뿐만 아니라, 다른 기간들에 대해서도 저자와 카테고리별 매출액을 출력하는 것을 확인할 수 있다.

저작자표시 비영리 변경금지 (새창열림)

'Algorithm Solving > SQL' 카테고리의 다른 글

[programmers] SQL Lv. 4 - 그룹별 조건에 맞는 식당 목록 출력하기  (1) 2025.01.15
[programmers] SQL Lv. 3 - 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기  (0) 2025.01.14
[programmers] SQL Lv. 4 - 주문량이 많은 아이스크림들 조회하기  (0) 2025.01.10
[programmers] SQL Lv. 3 - 조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기  (1) 2025.01.09
[programmers] SQL Lv. 4 - 우유와 요거트가 담긴 장바구니  (1) 2025.01.08
'Algorithm Solving/SQL' 카테고리의 다른 글
  • [programmers] SQL Lv. 4 - 그룹별 조건에 맞는 식당 목록 출력하기
  • [programmers] SQL Lv. 3 - 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기
  • [programmers] SQL Lv. 4 - 주문량이 많은 아이스크림들 조회하기
  • [programmers] SQL Lv. 3 - 조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기
기만나🐸
기만나🐸
공부한 내용을 기록합시다 🔥🔥🔥
  • 기만나🐸
    기만나의 공부 기록 🤓
    기만나🐸
  • 전체
    오늘
    어제
    • ALL (147)
      • TIL (Today I Learned) (56)
      • Dev Projects (15)
      • Algorithm Solving (67)
        • Java (52)
        • SQL (15)
      • Certifications (8)
        • 정보처리기사 실기 (8)
  • 인기 글

  • 태그

    자료구조
    jwt
    Subquery
    다이나믹프로그래밍
    greedy
    백트래킹
    그리디
    websocket
    BFS
    완전탐색
    DFS
    java
    Firebase
    programmers
    CSS
    GROUP BY
    join
    Google Fonts
    javascript
    백준
    mysql
    jQuery
    jpa
    sql
    프로그래머스
    BOJ
    시뮬레이션
    bootstrap
    dp
    HTML
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
기만나🐸
[programmers] SQL Lv. 4 - 저자 별 카테고리 별 매출액 집계하기
상단으로

티스토리툴바