sql - 将日期列表转换为 DateFrom/DateTo 范围的最佳方法
问题描述
我有一张每天每件商品的价格表。以下是数据存储方式的示例:
Date | Item | Price
--------------------------
2020-01-01 | Item1 | 5.0
2020-01-02 | Item1 | 5.0
2020-01-03 | Item1 | 5.0
2020-01-04 | Item1 | 6.0
2020-01-05 | Item1 | 6.0
2020-01-06 | Item1 | 7.0
2020-01-07 | Item1 | 9.0
2020-01-08 | Item1 | 5.0
2020-01-09 | Item1 | 5.0
我想通过按项目将数据分组并找到价格有效的最小和最大日期来“压缩”表格。
上述示例的结果应如下所示:
DateFrom | DateTo | Item | Price
----------------------------------------
2020-01-01 | 2020-01-03 | Item1 | 5.0
2020-01-04 | 2020-01-05 | Item1 | 6.0
2020-01-06 | 2020-01-06 | Item1 | 7.0
2020-01-07 | 2020-01-07 | Item1 | 9.0
2020-01-08 | 2020-01-09 | Item1 | 5.0
如何在 T-SQL 中实现这一点?
解决方案
这是一种差距和孤岛问题。这里的关键观察是从日期中减去枚举系列是恒定的——当相邻日期的值相同时:
select min(date), max(date), item, price
from (select t.*,
row_number() over (partition by item, price order by date) as seqnum
from t
) t
group by item, price,
dateadd(day, -seqnum, date);
请注意,此公式假设您每天都有一个日期(我想对于每个项目)。如果不是这种情况,请提出一个新问题。需要一种不同的方法——最好的方法取决于问题的确切性质。
推荐阅读
- spring-mvc - Spring组件扫描错误(schema_reference.4:无法读取架构文档'https://www.springframework.org/schema/beans/spring-beans-4.3.xsd')
- pandas - 无法仅检索使用熊猫从列中提取值时遇到的第一个值
- java - 如何在 Spring boot restful api 和 Flask restful api 之间创建通信?
- ios - React Native Expo Ejected App,无法从设备获取推送令牌
- javascript - Vue refs 存在但 refs[key] 未定义
- spring-boot - 我如何更改 Zuul API 网关的读取超时
- vue.js - 为什么我导入的 VueJS 组件不显示?
- java - 如何通过 Java 使用 Selenium 点击元素
- openstack - 禁用在 OVH OpenStack 对象存储中列出对象的功能
- javascript - Javascript lerp 函数没有给出准确的答案