문제
Write a solution to find the prices of all products on 2019-08-16. Assume the price of all products before any change is 10. Return the result table in any order.
2019-08-16일의 제품 가격을 구해야한다. 이후에 가격이 정해졌다면 기본가격인 10으로 계산해야한다.
테이블 & 예제
[Products]
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| product_id | int |
| new_price | int |
| change_date | date |
+---------------+---------+
[Examples]
Input:
Products table:
+------------+-----------+-------------+
| product_id | new_price | change_date |
+------------+-----------+-------------+
| 1 | 20 | 2019-08-14 |
| 2 | 50 | 2019-08-14 |
| 1 | 30 | 2019-08-15 |
| 1 | 35 | 2019-08-16 |
| 2 | 65 | 2019-08-17 |
| 3 | 20 | 2019-08-18 |
+------------+-----------+-------------+
Output:
+------------+-------+
| product_id | price |
+------------+-------+
| 2 | 50 |
| 1 | 35 |
| 3 | 10 |
+------------+-------+
풀이
아..잊고있던 Union을 활용하는 문제였다.
역시 생각을 유연하게 해야하는데 더 많은 선택지를 고려하는 연습이 부족한가 싶다. 그래도 잘하고있다!!
Solution에서 가져와서 풀이를 작성한다.
1. 2019-08-16 이후에 변경되는 컬럼들만을 선택해서 제품가격을 10으로 변경한다.
: 이걸 CTE를 이용해서 기존 데이터안에 같이 들어가게 해주었는데 16일에 가장 근접한 가격을 찾는데 어려움이 많았다.
오히려 이렇게 16일 이후의 날짜만을 모아서 컬럼을 생성해주는 것이 더 편리하다.
SELECT
DISTINCT(product_id),
10 AS price,
change_date
FROM products
GROUP BY product_id
HAVING
min(change_date) > '2019-08-16'
| product_id | price | change_date |
| ---------- | ----- | ----------- |
| 3 | 10 | 2019-08-18 |
2. 16일 이전의 값에 대해서 가장 최신 가격을 산출해야한다.
방식은 이러하다. 각 product_id 별로 change_date의 max값을 가져와서 동일한 열만을 추출한다.
WITH temp AS (
SELECT
product_id,
new_price,
change_date,
max(change_date) OVER (PARTITION BY product_id ORDER BY product_id)AS recent_date
FROM
products
WHERE
change_date <= '2019-08-16'
)
SELECT product_id, new_price AS price
FROM temp
WHERE change_date = recent_date;
3. 합친다!! > UNION, 전체 코드는 이러하다.
WITH temp AS (
SELECT
product_id,
new_price,
change_date,
max(change_date) OVER (PARTITION BY product_id ORDER BY product_id)AS recent_date
FROM
products
WHERE
change_date <= '2019-08-16'
)
SELECT product_id, new_price AS price
FROM temp
WHERE change_date = recent_date
UNION
SELECT
DISTINCT(product_id),
10 AS price
FROM products
GROUP BY product_id
HAVING
min(change_date) > '2019-08-16'
참고) UNION & UNION ALL
[UNION]
여러 쿼리문들을 합쳐서 하나의 쿼리문으로 만들어주는 방법이다.
- 중복된 값을 제거하고 보여준다는 특징이 있다!
- 이 떄문에 UNION ALL 보다 속도가 느리다
[UNION ALL]
여러 쿼리문들을 합쳐서 하나의 쿼리문으로 만들어주는 방법이다. (??)
- 차이점은 중복된 값을 모두 보여준다는 점이다.
[JOIN과의 차이점]
JOIN은 열을 기준으로 결합한다는점, UNION은 행으로 결합한다는 점이 차이점이다!
'코딩테스트 > SQL' 카테고리의 다른 글
SQL > LeetCode 1204. Last Person to Fit in the Bus (MySQL) (0) | 2024.06.12 |
---|---|
SQL > LeetCode Problem Solving: Product Price at a Given Date (AI.ver) (0) | 2024.06.11 |
SQL > LeetCode 180. Consecutive Numbers (MySQL) (0) | 2024.06.10 |
SQL > LeetCode 619. Biggest Single Number (MySQL) (0) | 2024.06.07 |
SQL > LeetCode 1070. Product Sales Analysis III (MySQL) (0) | 2024.06.06 |