前言
练习sql语句,所有题目来自于力扣(https://leetcode.cn/problemset/database/)的免费数据库练习题。
今日题目:
1164.指定日期的铲平价格
表:Products
列名 | 类型 |
---|---|
product_id | int |
new_price | int |
change_date | date |
(product_id, change_date) 是此表的主键(具有唯一值的列组合)。
这张表的每一行分别记录了 某产品 在某个日期 更改后 的新价格。
编写一个解决方案,找出在 2019-08-16 时全部产品的价格,假设所有产品在修改前的价格都是 10 。
以 任意顺序 返回结果表。
我那不值一提的想法:
-
首先梳理表内容,题干一共给了一张产品数据表,记录了产品id,产品更新后的的价格,产品更新日期。
-
其次分析需求, 需要找出在2019-08-16时全部产品的价格
-
那么现在就有以下两种情况,
-
1.最大日期是小于或等于2019-08-16之前的一个日期的价格,那么价格就是16号的价格,或者是16号之前最近日期的一个价格
-
2.最小日期都是大于2019-08-16的,那么价格就是10
-
第二个需求我们很好解决,直接就是
min(change_date) > "2019-08-16"
-
难的是第一个需求,如何求得离16号最近的日期,在这里我通过datediff来计算,通过计算每个日期距离16号的距离,然后对距离进行降序排序,然后再提取排名第一的日期,就能得到距离16号最近的日期
-
但是这里我们还需要求每个产品的日期距离16号最近的日期,所以还需要分组求日期,在这里就会用到partition by ,对产品id进行分组。
-
最后再通过union将两个结果连接起来就能得到最终的结果
select product_id,new_price as price
from (
select *,rank() over (partition by product_id order by datediff(change_date,"2019-08-16") desc) as num
from Products
where change_date <= "2019-08-16"
) as a
where a.num = 1
union
select product_id,10 as price
from Products
group by product_id
having min(change_date) > "2019-08-16"
结果:
总结:
能运行就行。