문제

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은 행으로 결합한다는 점이 차이점이다!

+ Recent posts