我想知道是否存在现有的、完善的算法来对时态表执行合并操作。
作为一个最小的例子,假设我们有一个表 [pricedata]:
+------+------+--------+
| from | to | price |
+------+------+--------+
| 2008 | 2009 | 100 |
| 2009 | 2011 | 121 |
| 2011 | 2013 | 142 |
+------+------+--------+
(这里的 [to] 列应该是不包含自身的)。 现在,我们得到一些新数据来覆盖原始数据:
+------+------+--------+
| from | to | price |
+------+------+--------+
| 2010 | 2012 | 109 |
+------+------+--------+
预期结果应相应地拆分并重新排列价格:
+------+------+--------+
| from | to | price |
+------+------+--------+
| 2008 | 2009 | 100 |
| 2009 | 2010 | 121 |
| 2010 | 2012 | 109 |
| 2012 | 2013 | 142 |
+------+------+--------+
我故意省略了太多细节,因为问题是是否已经有一个重要的资源/算法已经做到了这一点。尽管我的网络搜索没有产生任何结果,但感觉很常见——需要足够的存在。
对于具有包含开始日期和独占结束日期的数据,重叠日期的测试将是
(A.FromDate < B.ToDate AND B.FromDate < A.ToDate)
。
在插入新行之前,您可以查询与插入的日期范围重叠的任何现有行,并调整现有的开始和结束日期。
类似:
DECLARE @InsertFrom INT = 2010
DECLARE @InsertTo INT = 2010
DECLARE @InsertPrice INT = 2010
UPDATE pricedata
SET
[from] = GREATEST([from], @InsertTo),
[to] = LEAST([to], @InsertFrom)
WHERE [from] < @InsertTo
AND @InsertFrom < [to]
INSERT pricedata([from], [to], price)
VALUES (@InsertFrom, @InsertTo, @InsertPrice)
请注意,如果新的日期范围完全覆盖一个或多个现有日期范围,您最终会得到退化行,其中
to < from
。您可能需要添加另一个语句来删除此类行。 (保留它们可能是无害的,因为检查 from <= lookup < to
的查找永远不会匹配。)