马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
一、问题描述
在现实的业务场景中,我们经常需要从数据库中获取特定时间点的数据信息。本题给定了一个名为 Products 的产品数据表,其中记录了产品在不同日期的价格变革环境。我们的任务是编写一个 SQL 办理方案,找出在 2019-08-16 时全部产品的价格,而且假设全部产品在最初(没有价格更改记录之前)的价格都是 10 。
二、表结构分析
Products 表的结构如下:
列名类型说明product_idint产品的唯一标识,用于区分不同的产品。new_priceint产品在某个日期更改后的新价格。change_datedate产品价格发生更改的日期,与 product_id 一起构成表的主键,确保每一条记录的唯一性。
三、解题思路
- 确定每个产品在 2019-08-16 之前的最后一次价格更改记录:我们需要找出每个产品在 2019-08-16 之前(包罗 2019-08-16)的最后一条价格更改记录,由于这条记录对应的价格就是 2019-08-16 时该产品的价格。
- 处理没有价格更改记录的产品:对于那些在 2019-08-16 之前没有价格更改记录的产品,我们要按照题目要求,将其价格设置为 10 。
- 整合结果:将上述两种环境的结果整合起来,得到最终的产品价格表,按任意次序返回。
四、SQL 代码实现
- -- 选择产品 ID 和价格
- SELECT
- product_id,
- -- 使用 COALESCE 函数处理没有价格更改记录的产品
- COALESCE(
- -- 子查询获取每个产品在 2019-08-16 之前的最后一次价格
- (SELECT new_price
- FROM Products
- WHERE product_id = p.product_id
- AND change_date <= '2019-08-16'
- ORDER BY change_date DESC
- LIMIT 1),
- 10
- ) AS price
- FROM
- (
- -- 子查询获取所有产品的 ID
- SELECT DISTINCT product_id
- FROM Products
- ) p;
复制代码
五、代码详细表明
1、最内层子查询:
- SELECT DISTINCT product_id
- FROM Products
复制代码
这个子查询的作用是获取 Products 表中全部不同的产品 ID 。由于我们需要思量全部的产品,即使某些产品在 2019-08-16 之前没有价格更改记录,也需要在结果中表现,所以先获取全部产品的 ID 。
2、中心子查询:
- (SELECT new_price
- FROM Products
- WHERE product_id = p.product_id
- AND change_date <= '2019-08-16'
- ORDER BY change_date DESC
- LIMIT 1)
复制代码
这个子查询是针对每个产品 ID 进行的。它从 Products 表中筛选出当前产品 ID 且价格更改日期在 2019-08-16 之前(包罗 2019-08-16)的记录,然后按照价格更改日期降序排列,最后取第一条记录,即该产品在 2019-08-16 之前的最后一次价格更改记录的价格。
3、COALESCE 函数:
- COALESCE(
- (子查询获取的价格),
- 10
- ) AS price
复制代码
COALESCE 函数的作用是返回参数列表中第一个非 NULL 的值。在这里,如果中心子查询获取到了产品的价格(即该产品在 2019-08-16 之前有价格更改记录),则返回该价格;如果中心子查询返回 NULL(即该产品在 2019-08-16 之前没有价格更改记录),则返回 10 ,符合题目中产品在修改前价格为 10 的要求。
4、最外层查询:
- SELECT
- product_id,
- COALESCE(...) AS price
- FROM
- (最内层子查询) p;
复制代码
最外层查询从最内层子查询获取的产品 ID 列表中,联合 COALESCE 函数获取的价格,构成最终的结果表,包含产品 ID 和对应的价格。
六、复杂度分析
- 时间复杂度:假设 Products 表中有 n 条记录,最内层子查询获取全部产品 ID 的时间复杂度为 (O(n)),由于需要遍历整个表来找出不同的产品 ID 。对于每个产品 ID ,中心子查询的时间复杂度也为 (O(n))(在最坏环境下,需要遍历整个表来查找符合条件的记录),由于有 m 个不同的产品 ID ((m leq n)),所以中心子查询的总时间复杂度为 (O(mn))。综合来看,总的时间复杂度为 (O(mn))。
- 空间复杂度:在查询过程中,我们没有使用额外的与数据规模相关的空间,只是对表中的数据进行了读取和处理,因此空间复杂度为 (O(1))。
七、测试用例验证
1、输入数据:
- -- 插入示例数据
- INSERT INTO Products (product_id, new_price, change_date) VALUES
- (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');
复制代码
2、预期输出:
- +------------+-------+
- | product_id | price |
- +------------+-------+
- | 2 | 50 |
- | 1 | 35 |
- | 3 | 10 |
- +------------+-------+
复制代码 3、验证过程:将上述 SQL 代码在数据库中运行,将得到的结果与预期输出进行对比,如果结果同等,则说明我们的代码实现是精确的。
感谢各位的阅读,后续将连续给大家讲解力扣中的算法题和数据库题,如果觉得这篇内容对你有资助,别忘了点赞和关注,后续还有更多精彩的算法分析与你分享!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |