首页 > 解决方案 > 将日期列表转换为 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 中实现这一点?

标签: sqlsql-servertsql

解决方案


这是一种差距和孤岛问题。这里的关键观察是从日期中减去枚举系列是恒定的——当相邻日期的值相同时:

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);

请注意,此公式假设您每天都有一个日期(我想对于每个项目)。如果不是这种情况,请提出一个问题。需要一种不同的方法——最好的方法取决于问题的确切性质。


推荐阅读