SELECT product_id,
COALESCE(ROUND(SUM(units * temp) / SUM(CASE WHEN temp !=0 THEN units ELSE 0 END), 2), 0) AS average_price
FROM (
SELECT p.product_id,
u.units,
CASE WHEN u.purchase_date <= p.end_date AND u.purchase_date >= p.start_date THEN p.price
ELSE 0 END AS temp
FROM Prices p
LEFT JOIN UnitsSold u ON p.product_id = u.product_id
) AS a
GROUP BY product_id
1. JOIN 할 때 Prices를 기준으로 JOIN해야 판매량이 없는 물건까지 같이 출력 가능
2. 조건을 만족할 때 가격을 가져오고, 조건을 만족하지 않는 경우 0을 가져오게끔 CASE문을 작성
3.FROM절 서브쿼리를 이용
4. 분모에서 실제 판매된 수량만큼을 가져오기 위해 temp가 0이 아닌 경우만 수량을 더하도록 CASE문을 작성
5. ROUND를 통해 문제에서 원하는 조건 달성
6. COALESCE를 통해 NULL 대신 0이 나오게 처리
그치만 너무 비효율적이죠?
Solution을 봐보겠습니다
1. 깔끔하게 JOIN하기
SELECT *
FROM Prices p
LEFT JOIN UnitsSold u ON p.product_id = u.product_id
AND u.purchase_date BETWEEN p.start_date AND p.end_date
ON을 사용해 JOIN의 기준이 될 column을 명시해주고
BETWEEN을 이용해 날짜 조건을 만족하는 경우 UnitsSold의 row들이 갖다붙을 수 있게끔 작성
2. IFNULL 함수를 이용해서 NULL인 경우를 처리
SELECT p.product_id,
IFNULL(ROUND(SUM(price * units) / SUM(units), 2), 0) AS average_price
FROM Prices p
LEFT JOIN UnitsSold u ON p.product_id = u.product_id
AND u.purchase_date BETWEEN p.start_date AND p.end_date
GROUP BY p.product_id
'SQL > 문제풀이' 카테고리의 다른 글
[LeetCode] primary-department-for-each-employee (0) | 2024.03.09 |
---|---|
[LeetCode] immediate-food-delivery-ii (0) | 2024.03.05 |
[LeetCode] monthly-transactions (0) | 2024.03.04 |
[LeetCode] students-and-examinations 📌 (0) | 2024.03.04 |
[LeetCode] confirmation-rate (0) | 2024.03.04 |