Description
Table: Products
| Column Name | Type |
|---|---|
| product_id | int |
| new_price | int |
| change_date | date |
- (
product_id,change_date) is the primary key (combination of columns with unique values) of this table. - Each row of this table indicates that the price of some product was changed to a new price at some date.
Problem Statement
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. The result format is in the following example.
Example 1:
Input:
Productstable:
| 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 |
Solution
The problem is asking to find the prcie for each product on 2019-08-16. That means we can ignore all changes after this date.
1SELECT product_id, change_date, new_price
2 FROM Products
3 WHERE change_date <= '2019-08-16'
4 ORDER BY product_id, change_date
| product_id | change_date | new_price |
|---|---|---|
| 1 | 2019-08-14 | 20 |
| 1 | 2019-08-15 | 30 |
| 1 | 2019-08-16 | 35 |
| 2 | 2019-08-14 | 50 |
Out of these prices for product_id=1, you need the first value when ordered by change_date in descending order for each product_id.
1SELECT product_id,
2 FIRST_VALUE(new_price) OVER (PARTITION BY product_id ORDER BY change_date DESC)
3 FROM Products
4 WHERE change_date <= '2019-08-16'
5 ORDER BY product_id, change_date
| product_id | new_price |
|---|---|
| 1 | 35 |
| 1 | 35 |
| 1 | 35 |
| 2 | 50 |
The next step is step is to fetch only distinct products from the result using DISTINCT keyword.
1SELECT DISTINCT product_id,
2 FIRST_VALUE(new_price) OVER (PARTITION BY product_id ORDER BY change_date DESC) AS new_price
3 FROM Products
4 WHERE change_date <= '2019-08-16';
| product_id | new_price |
|---|---|
| 1 | 35 |
| 2 | 50 |
Next, you need to report prices for all products. Remember that if a product’s price is never change, it had a default value of 10. So, you still need to output price based on that.
1WITH changed_products AS (
2 SELECT DISTINCT product_id,
3 FIRST_VALUE(new_price) OVER (PARTITION BY product_id ORDER BY change_date DESC) AS price
4 FROM Products
5 WHERE change_date <= '2019-08-16'
6) SELECT p.product_id,
7 CASE WHEN cp.price IS NULL THEN 10 ELSE cp.price END AS price
8 FROM (SELECT DISTINCT product_id FROM Products) p
9 LEFT OUTER JOIN changed_products cp
10 ON p.product_id = cp.product_id;


Comments