SQL문제풀이/LeetCode

[SQL풀이][LeetCode][easy] 1251. Average Selling Price

정호랭이 2023. 11. 5. 13:30

https://leetcode.com/problems/average-selling-price/description/

 

Average Selling Price - LeetCode

Can you solve this real interview question? Average Selling Price - Table: Prices +---------------+---------+ | Column Name | Type | +---------------+---------+ | product_id | int | | start_date | date | | end_date | date | | price | int | +---------------

leetcode.com

 

문제설명

Prices와 UnitsSold 테이블을 참고하여 상품ID별 평균 판매가격을 계산하라.

 

- Prices: 상품 ID와 기간별 가격
- UnitsSold: 상품 ID, 판매일자 및 판매량

 

 

접근방법
1. Prices 테이블과 UnitsSold 테이블을 join하여 각 판매일에 해당하는 판매금액(revenue)을 계산한다.

2. 각 상품별 판매금액의 합계와 판매량을 이용하여 평균 판매가격을 계산한다.

 

 

풀이코드

-- 각 판매일에 해당하는 price 정보를 join한다. 
WITH RevenueSold AS (
    SELECT 
        p.product_id,
        p.price,
        us.units,
        p.price * us.units as revenue
    FROM 
        Prices AS p, 
        UnitsSold AS us
    WHERE 
        p.product_id = us.product_id AND
        us.purchase_date BETWEEN p.start_date AND p.end_date 
)

-- 각 판매일에 해당하는 판매금액을 계산한다.
AvgSellingPrices AS(
    SELECT 
        product_id,
        ROUND(SUM(revenue) / SUM(units), 2) AS 'average_price'
    FROM RevenueSold
    GROUP BY product_id
)

-- 각 상품별 판매금액의 합계와 판매량을 이용하여 평균 판매가격을 계산한다.
SELECT 
    DISTINCT product_id,
    IFNULL(asp.average_price, 0) AS average_price
FROM Prices AS p
LEFT JOIN AvgSellingPrices AS asp
USING (product_id)

 

 

추가 설명

CTE

- RevenueSold : 두 테이블을 JOIN한 결과를 저장하는 테이블. 판매일자 별 판매금액(revenue) 컬럼 생성.
- AvgSellingPrices : GROUP BY 를 사용하여 각 상품별 평균 판매가격을 계산한 결과를 저장하는 테이블.

 

Main Query

- test case 中 Prices 테이블에 가격정보가 있지만 UnitsSold 테이블에 판매기록이 없는 product_id가 존재함. 

- 문제에서, 판매이력이 없는 product_id의 평균 판매가격은 0으로 출력을 요구하기 때문에, Prices 테이블 product_id에 AvgSellingPrices에서 구한 값을 join 하는 방식으로 문제 해결.

 

 

개선 방법

- 범주로 주어진 date(start_date, end_date)와 단일 date(purchase_date)를 JOIN하는 방법이 이 문제의 핵심

- 제한 시간내에 문제를 풀기위하여 CTE를 이용하여 단계별로 문제풀이 진행

- RevenueSold테이블의 WHERE절을 JOIN 뒤 ON절에 똑같이 적용하여 더욱 간단한 코드로 풀이 가능

SELECT 
    p.product_id, 
    IFNULL(ROUND(SUM(units*price)/SUM(units),2),0) AS average_price
FROM Prices AS p 
LEFT JOIN UnitsSold AS us
ON 
    p.product_id = us.product_id AND
    us.purchase_date BETWEEN start_date AND end_date
GROUP BY product_id