【LeetCode 题解】数据库:1164.指定日期的产品价格

打印 上一主题 下一主题

主题 1849|帖子 1849|积分 5547

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

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 代码实现

  1. -- 选择产品 ID 和价格
  2. SELECT
  3.     product_id,
  4.     -- 使用 COALESCE 函数处理没有价格更改记录的产品
  5.     COALESCE(
  6.         -- 子查询获取每个产品在 2019-08-16 之前的最后一次价格
  7.         (SELECT new_price
  8.          FROM Products
  9.          WHERE product_id = p.product_id
  10.            AND change_date <= '2019-08-16'
  11.          ORDER BY change_date DESC
  12.          LIMIT 1),
  13.         10
  14.     ) AS price
  15. FROM
  16.     (
  17.         -- 子查询获取所有产品的 ID
  18.         SELECT DISTINCT product_id
  19.         FROM Products
  20.     ) p;
复制代码


五、代码详细表明

1、最内层子查询

  1. SELECT DISTINCT product_id
  2. FROM Products
复制代码

这个子查询的作用是获取 Products 表中全部不同的产品 ID 。由于我们需要思量全部的产品,即使某些产品在 2019-08-16 之前没有价格更改记录,也需要在结果中表现,所以先获取全部产品的 ID 。

2、中心子查询

  1. (SELECT new_price
  2. FROM Products
  3. WHERE product_id = p.product_id
  4.    AND change_date <= '2019-08-16'
  5. ORDER BY change_date DESC
  6. LIMIT 1)
复制代码

这个子查询是针对每个产品 ID 进行的。它从 Products 表中筛选出当前产品 ID 且价格更改日期在 2019-08-16 之前(包罗 2019-08-16)的记录,然后按照价格更改日期降序排列,最后取第一条记录,即该产品在 2019-08-16 之前的最后一次价格更改记录的价格。

3、COALESCE 函数

  1. COALESCE(
  2.     (子查询获取的价格),
  3.     10
  4. ) AS price
复制代码

COALESCE 函数的作用是返回参数列表中第一个非 NULL 的值。在这里,如果中心子查询获取到了产品的价格(即该产品在 2019-08-16 之前有价格更改记录),则返回该价格;如果中心子查询返回 NULL(即该产品在 2019-08-16 之前没有价格更改记录),则返回 10 ,符合题目中产品在修改前价格为 10 的要求。

4、最外层查询

  1. SELECT
  2.     product_id,
  3.     COALESCE(...) AS price
  4. FROM
  5.     (最内层子查询) 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、输入数据
  1. -- 插入示例数据
  2. INSERT INTO Products (product_id, new_price, change_date) VALUES
  3. (1, 20, '2019-08-14'),
  4. (2, 50, '2019-08-14'),
  5. (1, 30, '2019-08-15'),
  6. (1, 35, '2019-08-16'),
  7. (2, 65, '2019-08-17'),
  8. (3, 20, '2019-08-18');
复制代码

2、预期输出
  1. +------------+-------+
  2. | product_id | price |
  3. +------------+-------+
  4. | 2          | 50    |
  5. | 1          | 35    |
  6. | 3          | 10    |
  7. +------------+-------+
复制代码
3、验证过程:将上述 SQL 代码在数据库中运行,将得到的结果与预期输出进行对比,如果结果同等,则说明我们的代码实现是精确的。

感谢各位的阅读,后续将连续给大家讲解力扣中的算法题和数据库题,如果觉得这篇内容对你有资助,别忘了点赞和关注,后续还有更多精彩的算法分析与你分享!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表