题目描述

(通过次数11,451 | 提交次数19,024,通过率60.19%)

产品数据表: Products
+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| product_id    | int     |
| new_price     | int     |
| change_date   | date    |
+---------------+---------+
这张表的主键是 (product_id, change_date)。
这张表的每一行分别记录了 某产品 在某个日期 更改后 的新价格。

写一段 SQL来查找在2019-08-16 时全部产品的价格,假设所有产品在修改前的价格都是10 。
以 任意顺序 返回结果表。

查询结果格式如下例所示。
示例 1:
输入:
Products 表:
+------------+-----------+-------------+
| 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  |
+------------+-----------+-------------+
输出:
+------------+-------+
| product_id | price |
+------------+-------+
| 2          | 50    |
| 1          | 35    |
| 3          | 10    |
+------------+-------+

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/product-price-at-a-given-date
//测试数据
Create table If Not Exists Products (product_id int, new_price int, change_date date);

insert into Products (product_id, new_price, change_date) values ('1', '20', '2019-08-14');
insert into Products (product_id, new_price, change_date) values ('2', '50', '2019-08-14');
insert into Products (product_id, new_price, change_date) values ('1', '30', '2019-08-15');
insert into Products (product_id, new_price, change_date) values ('1', '35', '2019-08-16');
insert into Products (product_id, new_price, change_date) values ('2', '65', '2019-08-17');
insert into Products (product_id, new_price, change_date) values ('3', '20', '2019-08-18');

解题思路

源表Products中保存了产品价格的修改记录,一天只会有一条修改记录。
题目要求:查询所有产品在2019年8月16日的价格。
首先,题目要求查询所有产品的价格,包括2019年8月16日以前没有价格变更的产品。
因为题目只给出了一张源表,所以只能对Products表去重获取所有的产品信息。但实际上,这样做是不严谨的,因为也许存在某个产品,价格从来没有变更过,也就不会出现在Products表中。
接下来就是如何获取产品在2019年8月16日的产品价格。
根据对Products表的分析,截止到某一天的产品价格,是这一天之前最后一次修改后的产品价格。
那么,我们可以计算出2019年8月16日前,每一个产品的最后一次修改日期,然后获取到最后一次修改日期的产品价格即可。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
with
tmp as (
    select
        distinct product_id
    from Products
)
select
    a.product_id,
    coalesce(b.new_price,10) price
from tmp a
left join Products b
on a.product_id = b.product_id
and (b.product_id,b.change_date) in (
    select
        product_id,
        max(change_date) change_date
    from Products
    where change_date <= '2019-08-16'
    group by product_id
);
picture loss